Scala:滑动(N,N)vs分组(N)

时间:2015-09-30 19:47:49

标签: scala

当我需要在n个元素的组中迭代集合而不重新处理任何元素时,我发现自己最近使用了滑动(n,n)。我想知道使用分组(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))

1 个答案:

答案 0 :(得分:14)

使用sliding代替grouped的原因仅适用于您希望拥有“{1}}窗口的情况”。长度不同于你滑动的长度。 by(也就是说,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更合适。