给定一个元素序列和一个谓词p
,我想生成一个序列序列,使得在每个子序列中,所有元素都满足p
或序列具有长度1
。此外,调用.flatten
结果应该会返回我的原始序列(因此不会重新排序元素)。
例如,给定:
val l = List(2, 4, -6, 3, 1, 8, 7, 10, 0)
val p = (i : Int) => i % 2 == 0
我想magic(l,p)
制作:
List(List(2, 4, -6), List(3), List(1), List(8), List(7), List(10, 0))
我知道.span
,但是该方法在第一次遇到不满足的值时停止p
并仅返回一对。
下面是一个候选实现。它做了我想要的,但是,好吧,让我们想哭。我希望有人能想出一些更惯用的东西。
def magic[T](elems : Seq[T], p : T=>Boolean) : Seq[Seq[T]] = {
val loop = elems.foldLeft[(Boolean,Seq[Seq[T]])]((false,Seq.empty)) { (pr,e) =>
val (lastOK,s) = pr
if(lastOK && p(e)) {
(true, s.init :+ (s.last :+ e))
} else {
(p(e), s :+ Seq(e))
}
}
loop._2
}
(请注意,我并不特别关心保留 . 的实际类型Seq
。)