在Scala得分和总和的最佳方式?

ada*_*m77 9 scala sum

有没有更好的方法:

val totalScore = set.foldLeft(0)( _ + score(_) )
Run Code Online (Sandbox Code Playgroud)

或这个:

val totalScore = set.toSeq.map(score(_)).sum
Run Code Online (Sandbox Code Playgroud)

我认为这是一个非常常见的操作,所以期待更时尚的东西:

val totalScore = set.sum( score(_) )
Run Code Online (Sandbox Code Playgroud)

Dan*_*ral 17

那么,还有其他方法可以编写它:

val totalScore = set.toSeq.map(score(_)).sum
val totalScore = set.toSeq.map(score).sum
val totalScore = set.toSeq map score sum
Run Code Online (Sandbox Code Playgroud)

如果下一行不以关键字开头,则最后一行可能需要在结尾处使用分号.也可以使用.view代替.toSeq,这将避免分配临时集合.但是,我不确定.view现在的行为(显示重复元素)是否正确.

  • 两步法的合理关注可能是表现 - 它创建了第二个列表,只是为了总结它.但是,您可以使用视图来避免这种开销:`set.view.map(score).sum`.分离映射和求和的关注避免了标准库中方法的爆炸.如果经常这样做,可以将`mapAndSum`添加到您自己的代码中. (3认同)
  • 这段代码有错误!也就是说,如果`set`确实是'Set [_]`类型,`score`将相同的值分配给`set`的两个元素(即`score(a)= score(b)`where`a`,` b`在`set`和`a!= b`)中,然后它们只被计算一次.因此,不仅"懒惰"`set.view.map.(score(_)).sum`更高效,它实际上是唯一正确的方法!(我实际上刚刚在我的代码中遇到过这个错误.) (2认同)

Mic*_*mer 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
Run Code Online (Sandbox Code Playgroud)

请注意,该Numeric特征仅存在于Scala 2.8中.

  • 米歇尔,我喜欢你的解决方案,我还以为我想使它成为更通用的一点点让比分在对象上工作,像"游戏",并返回一个数字:隐式高清traversableWithSum [A](T:Traversable的[A] )=新的{DEF sumWith [b](F:A => b)(隐式米:数字[b]):b = t.foldLeft(m.zero)((A,b)=> m.plus(一,f(b)))} (2认同)