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

wz3gfoph  于 5个月前  发布在  Scala
关注(0)|答案(2)|浏览(63)

最近,我发现自己在不重新处理任何元素的情况下需要对n个元素的集合进行重新排序时使用了sliding(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))

字符串

v2g6jxz6

v2g6jxz61#

使用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更合适。

jaql4c8m

jaql4c8m2#

import scala.util.Random

val measurements: Vector[Long] = {
   val random = new Random(2021)
   (1 to 100_000_000).map(_ => 10 + random.nextLong(90)).toVector
}

 
def time(block: => Unit): Long = {
   val start = System.nanoTime()
   block
   val end = System.nanoTime()
   (end - start) / 1000 / 1000
}

scala> time {measurements.grouped(2).collect { case Seq(a, b) if a < b => b }.size}
val res38: Long = 2367

scala> time {measurements.sliding(2,1).collect { case Seq(a, b) if a < b => b }.size} 
val res39: Long = 5174

字符串
sliding比2倍慢。
苹果Apple M1 Pro,16 GB

相关问题