基于谓词的Sum元素

时间:2014-11-24 12:33:49

标签: scala map iteration

考虑以下代码:

val definedFields: Int = datMap.values.map(x => if (x.isDefined) 1 else 0).sum

datMap是一个Map,其中值的类型为Option [Something_that_has_isDefined]

  • map()。sum会迭代2次还是构建表达式树和 执行一次。
  • 有没有办法缩短?一种方法是折叠它。

3 个答案:

答案 0 :(得分:4)

方法count计算满足谓词的元素数。

datMap.values.count{_.isDefined}
  

map()。sum迭代2次,还是构建表达式树并执行一次。

通过常规收集,例如List,您将在map之后获得一个中间收藏。对于Stream或任何view等惰性集合,您将在map之后获得包装。

另见Scala’s Collections Library/Views

答案 1 :(得分:3)

考虑flattenflatMap这样,

datMap.values.flatten.size

其中flatten修剪出未定义的值,或者在一遍中修剪

datMap.flatMap(_._2).size

答案 2 :(得分:1)

有许多方法,一种是fold,就像你说的那样:

scala> List(Some(1), None, Some(3), None, Some(8))
res0: List[Option[Int]] = List(Some(1), None, Some(3), None, Some(8))

scala> res0.foldLeft(0)(_ + _.map(_ => 1).getOrElse(0))
res1: Int = 3

使用fold允许一次迭代,映射然后使用sum使用两次迭代,一次用于map,另一次用于sum,因为后者是使用{{ 1}}:

foldLeft