Подтвердить что ты не робот

Scala: скользящая (N, N) и сгруппированная (N)

В последнее время я обнаружил, что я использовал скользящие (n, n), когда мне нужно итерировать коллекции в группах из n элементов без повторной обработки любого из них. Мне было интересно, было бы правильнее перебирать эти коллекции, используя grouped (n). Мой вопрос в том, есть ли специальная причина использовать тот или иной для этого конкретного случая с точки зрения производительности.

val listToGroup = List(1,2,3,4,5,6,7,8)
listToGroup: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8)

listToGroup.sliding(3,3).toList
res0: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6), List(7, 8))

listToGroup.grouped(3).toList
res1: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6), List(7, 8))
4b9b3361

Ответ 1

Причина использования sliding вместо grouped действительно применима только тогда, когда вы хотите, чтобы "окна" имели длину, отличную от той, на которую вы "скользите" (то есть, используя sliding(m, n) где m != n):

listToGroup.sliding(2,3).toList
//returns List(List(1, 2), List(4, 5), List(7, 8))

listToGroup.sliding(4,3).toList
//returns List(List(1, 2, 3, 4), List(4, 5, 6, 7), List(7, 8))

Как указывает в комментарии som-snytt, разницы в производительности не будет, так как они оба реализованы в Iterator возвращая новый GroupedIterator. Тем не менее, проще написать grouped(n) чем sliding(n, n), и ваш код будет чище и более очевиден в предполагаемом поведении, поэтому я бы порекомендовал grouped(n).

В качестве примера того, где использовать sliding, рассмотрим этот пример, где grouped просто недостаточно:

Дан список чисел, подсписок длиной 4 с наибольшей суммой.

Теперь, оставив в стороне тот факт, что подход динамического программирования может дать более эффективный результат, это можно решить следующим образом:

def maxLengthFourSublist(list: List[Int]): List[Int] = {
    list.sliding(4,1).maxBy(_.sum)
}

Если бы вы использовали grouped здесь, вы не получили бы все подсписки, поэтому sliding более уместно.