在 Scala 中得分和求和的最佳方式?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2879554/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:09:43  来源:igfitidea点击:

Best way to score and sum in Scala?

scalasum

提问by adam77

Is there a better way of doing this:

有没有更好的方法来做到这一点:

val totalScore = set.foldLeft(0)( _ + score(_) )

or this:

或这个:

val totalScore = set.toSeq.map(score(_)).sum

I think it's quite a common operation so was expecting something sleeker like:

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

val totalScore = set.sum( score(_) )

回答by Daniel C. Sobral

Well, there are alternative ways to write it:

好吧,还有其他的写法:

val totalScore = set.toSeq.map(score(_)).sum
val totalScore = set.toSeq.map(score).sum
val totalScore = set.toSeq map score sum

The last one may require a semi-colon at the end if the next line doesn't start with a keyword. One can also use .viewinstead of .toSeq, which would avoid allocating a temporary collection. However, I'm not sure the .view's present behavior (of showing repeated elements) is the correct one.

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

回答by Michel Kr?mer

Seq.sumdoes not take a function which could be used to score the sum. You could define an implicit conversion which "pimps" Traversable:

Seq.sum不采用可用于对总和进行评分的函数。您可以定义“皮条客”的隐式转换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

Please note that the Numerictrait only exists in Scala 2.8.

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

回答by Randall Schulz

Simpler:

更简单:

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

With your score method:

使用您的评分方法:

scoreSet.reduceLeft(_ + score(_))

Warning, though, this fails is the collection being reduced is empty while fold does not:

警告,但是,这失败是减少的集合是空的,而 fold 不是:

scala> val is0 = Set[Int]()
is0: scala.collection.immutable.Set[Int] = Set()

scala> is0.foldLeft(0)(_ + _)
res1: Int = 0

回答by Randall Schulz

Alternately, the Seq#sumoverload that takes an implicit conversion to Numericcould be used if the type in the collection to be scored / summed does not itself have an addition operator. However, because it's an implicit conversion parameter, it won't be applied unless required to make the reduce closure type-check.

或者,如果要评分/求和的集合中的类型本身没有加法运算符,则可以使用采用Seq#sum隐式转换的重载Numeric。但是,因为它是一个隐式转换参数,除非需要进行reduce 闭包类型检查,否则不会应用它。