有没有更好的方法:
val totalScore = set.foldLeft(0)( _ + score(_) )
或者这个:
val totalScore = set.toSeq.map(score(_)).sum
我认为这是一种非常常见的操作,所以期待更像时尚的东西:
val totalScore = set.sum( score(_) )
答案 0 :(得分:17)
嗯,还有其他方法可以写它:
val totalScore = set.toSeq.map(score(_)).sum
val totalScore = set.toSeq.map(score).sum
val totalScore = set.toSeq map score sum
如果下一行不以关键字开头,则最后一行可能需要在结尾处使用分号。也可以使用.view
代替.toSeq
,这样可以避免分配临时集合。但是,我不确定.view
的当前行为(显示重复元素)是否正确。
答案 1 :(得分:5)
Seq.sum
没有采用可用于对总和进行评分的函数。您可以定义“pimps”Traversable
:
implicit def traversableWithSum[A](t: Traversable[A])(implicit m: Numeric[A]) = new {
def sumWith(f: A => A) = t.foldLeft(m.zero)((a, b) => m.plus(a, f(b)))
}
def score(i: Int) = i + 1
val s = Set(1, 2, 3)
val totalScore = s.sumWith(score _)
println(totalScore)
=> 9
请注意,Numeric
特征仅存在于Scala 2.8中。
答案 2 :(得分:1)
简单:
scala> val is1 = Set(1, 4, 9, 16)
is1: scala.collection.immutable.Set[Int] = Set(1, 4, 9, 16)
scala> is1.reduceLeft(_ + _)
res0: Int = 30
使用您的分数方法:
scoreSet.reduceLeft(_ + score(_))
警告,但是失败的是减少的集合是空的而折叠不是:
scala> val is0 = Set[Int]()
is0: scala.collection.immutable.Set[Int] = Set()
scala> is0.foldLeft(0)(_ + _)
res1: Int = 0
答案 3 :(得分:1)
或者,如果要评分/求和的集合中的类型本身没有加法运算符,则可以使用隐式转换为Seq#sum
的{{1}}重载。但是,因为它是一个隐式转换参数,所以除非需要进行reduce闭包类型检查,否则不会应用它。