我对scala / spark的列表匹配有一个一般性的问题。假设我有以下形式的布尔列表:
List(true, false, false ,true, true)
我希望将此布尔列表转换为:
List(1, 1, 1, 2, 3)
这样每次有一个true时,List加1,每次有一个false,它输出前一个结果。我认为有一些非常有效的方法可以在没有循环的情况下做到这一点,但是现在想不出来..
答案 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。