当您并不总是需要检查列表的所有元素时,如何提高 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 集合,例如 Iterator 或 LazyList (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)
例如,如果您有数百万个元素,但通常只需要检查前一百万个元素(例如,如果您正在累加和并且在某个最大值处饱和,或者您正在构建其他一些复杂的数据结构,但你在检查前 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 集合,例如 Iterator 或 LazyList (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)