当您并不总是需要检查列表的所有元素时,如何提高 foldLeft(或 scanLeft)的性能?

How do you improve the performance of foldLeft (or scanLeft) when you don't always need to examine all the elements of a list?

例如,如果您有数百万个元素,但通常只需要检查前一百万个元素(例如,如果您正在累加和并且在某个最大值处饱和,或者您正在构建其他一些复杂的数据结构,但你在检查前 M 个元素后完成)。 FoldLeft 总是强制您遍历整个序列。理想情况下,您可以提供一个让 foldLeft 知道您已完成的谓词。

如果 scanLeft 被延迟计算(?),也许 scanLeft 与查找(查找第一个有效元素)一起可以完成此操作。我相信这样的东西可以在 Haskell 中使用,但不确定 Scala。

numbers.scanLeft(0)((a, b) => a + b).find(_ >= 100)

因此,如果 numbers = List(100,0,9,10),则 scanLeft 将只查看第一个元素。

scanLeft 为已经 lazy 的集合生成一个 lazy 集合,例如 IteratorLazyList Strem 先于 2.13。因此,您可以使用它提前中止。
例如:

LazyList.continually(100)
  .scanLeft(0) { case (acc, n) => acc + n }
  .takeWhile(_ < 1000)
  .toList
// res: List[Int] = List(0, 100, 200, 300, 400, 500, 600, 700, 800, 900)

List(0, 100, 5, 300)
  .iterator
  .map(i => { println(i); i })
  .scanLeft(0) { case (acc, n) => acc + n }
  .find(_ >= 100)
// 0
// 100
// res: Option[Int] = Some(100)