【问题标题】:scala match from list of Boolean to list of summed Int从布尔列表到总和 Int 列表的 scala 匹配
【发布时间】:2015-03-06 15:27:11
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • 是的,为真时加一个
  • 这与 apache-spark 有什么关系?

标签: scala


【解决方案1】:

您可以为此使用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 为其播种,最后我只使用List 中的tail 放弃了它。否则我会有List(0, 1, 1, 1, 2, 3)

【讨论】:

  • 我认为tail 会比drop(1) 更清晰一些。
  • 我想。这真的很边缘。
【解决方案2】:

听起来您正在寻找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

【讨论】:

  • 感谢您的解决方案,我从未使用过 scanLeft,经常不得不解决复制、删除第一个/最后一个并将它们压缩在一起的问题。不错的一个
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-17
  • 1970-01-01
  • 1970-01-01
  • 2013-12-05
  • 1970-01-01
  • 1970-01-01
  • 2018-10-01
相关资源
最近更新 更多