scala匹配从布尔列表到求和Int列表

时间:2015-03-06 15:27:11

标签: scala

我对scala / spark的列表匹配有一个一般性的问题。假设我有以下形式的布尔列表:

List(true, false, false ,true, true)

我希望将此布尔列表转换为:

List(1, 1, 1, 2, 3)

这样每次有一个true时,List加1,每次有一个false,它输出前一个结果。我认为有一些非常有效的方法可以在没有循环的情况下做到这一点,但是现在想不出来..

2 个答案:

答案 0 :(得分:5)

您可以使用scanLeft

List(true, false, false, true, true).scanLeft(0) { case (sum, next) =>
    if(next) sum + 1 else sum
}.tail

res45: List[Int] = List(1, 1, 1, 2, 3)

scanLeft可帮助您生成一系列部分和,这基本上就是您所拥有的。在case (sum, next)中,sum表示当前的累计值,next表示List中的下一个元素。所以我们检查next是否为真,如果是,则添加一个,否则返回当前总和。在scanLeft内返回的每个元素都会添加到最终List

请注意,我必须使用0播种,我最后只删除tail的{​​{1}}。否则我会有List

答案 1 :(得分:3)

听起来像是在寻找scanLeft:

val bs = List(true, false, false, true, true)
val is = bs.scanLeft(0){ case (acc, el) => if (el) acc + 1 else acc }.tail
// "is" is equal to List[Int] = List(1, 1, 1, 2, 3)

如果你选择完整列表而不是尾部,结果为List[Int] = List(0, 1, 1, 1, 2, 3),因为起始值为0。

这是scaladoc for scanLeft