当某些条件成立时 Scala FoldLeft

2023-11-26

如何在 Scala 中模拟以下行为?即在满足累加器上的某些特定条件时继续折叠。

def foldLeftWhile[B](z: B, p: B => Boolean)(op: (B, A) => B): B

例如

scala> val seq = Seq(1, 2, 3, 4)
seq: Seq[Int] = List(1, 2, 3, 4)
scala> seq.foldLeftWhile(0, _ < 3) { (acc, e) => acc + e }
res0: Int = 1
scala> seq.foldLeftWhile(0, _ < 7) { (acc, e) => acc + e }
res1: Int = 6

UPDATES:

根据@Dima 的回答,我意识到我的意图有点副作用。所以我让它同步takeWhile,即如果谓词不匹配,则不会有任何进展。并添加更多示例以使其更清晰。 (注意:这不适用于Iterators)


首先,请注意您的示例似乎是错误的。如果我正确理解你的描述,结果应该是1(谓词所依据的最后一个值_ < 3满意),不6

最简单的方法是使用return声明,这在 scala 中是非常不受欢迎的,但我想,为了完整起见我会提到它。

def foldLeftWhile[A, B](seq: Seq[A], z: B, p: B => Boolean)(op: (B, A) => B): B = foldLeft(z) { case (b, a) => 
   val result = op(b, a) 
   if(!p(result)) return b
   result
}

由于我们想避免使用 return,scanLeft可能是一种可能性:

seq.toStream.scanLeft(z)(op).takeWhile(p).last

这有点浪费,因为它累积了所有(匹配的)结果。 你可以使用iterator代替toStream为了避免这种情况,但是Iterator不具有.last由于某种原因,因此,您必须明确地额外扫描它:

 seq.iterator.scanLeft(z)(op).takeWhile(p).foldLeft(z) { case (_, b) => b }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当某些条件成立时 Scala FoldLeft 的相关文章

随机推荐