soc*_*soc 14 collections scala mapreduce sum higher-order-functions
考虑这个课程:
case class Person(val firstName: String, val lastName: String, age: Int)
val persons = Person("Jane", "Doe", 42) :: Person("John", "Doe", 45) ::
Person("Joe", "Doe", 43) :: Person("Doug", "Don", 65) ::
Person("Darius", "Don", 24) :: Person("Dora", "Don", 20) ::
Person("Dane", "Dons", 29) :: Nil
Run Code Online (Sandbox Code Playgroud)
为了得到所有人的年龄总和,我可以编写如下代码:
persons.foldLeft(0)(_ + _.age)
Run Code Online (Sandbox Code Playgroud)
但是如果我想使用sum,我需要先映射该值,代码如下所示:
persons.map(_.age).sum
Run Code Online (Sandbox Code Playgroud)
如何在不创建某些中间集合的情况下使用该sum方法?
(我知道这样的"优化"很可能在没有在紧密循环中运行时没有任何真正的性能差异,而且我也知道懒惰的视图等等.)
是否有可能像这样的代码
persons.sum(_.age)
Run Code Online (Sandbox Code Playgroud)
做什么foldLeft/ 做什么reduceLeft?
she*_*lic 12
你回答的是你自己.只需使用view:
persons.view.map(_.age).sum
Run Code Online (Sandbox Code Playgroud)
通过检查工作流程来说服自己:
persons.view.map { p =>
println("invoking age")
p.age
}.map { x =>
println("modifing age")
x + 0
}.sum
Run Code Online (Sandbox Code Playgroud)
VS:
persons.map { p =>
println("invoking age")
p.age
}.map { x =>
println("modifing age")
x + 0
}.sum
Run Code Online (Sandbox Code Playgroud)
Ale*_*nov 11
sum库中的方法不能以这种方式工作,但您可以编写自己的方法:
def mySum[T, Res](f: T => Res, seq: TraversableOnce[T])(implicit num: Numeric[Res]) =
seq.foldLeft(num.zero)((acc, b) => num.plus(acc, f(b)))
Run Code Online (Sandbox Code Playgroud)
您还可以添加隐式转换,以便您可以调用它seq.sum(f)而不是mySum(f, seq)(您可能需要一个不同的名称,sum以避免冲突):
case class SumTraversableOnce[T](val seq: TraversableOnce[T]) {
def sum[Res](f: T => Res)(implicit num: Numeric[Res]) = mySum(f, seq)(num)
}
implicit def toSumTraversableOnce[T](seq: TraversableOnce[T]) =
SumTraversableOnce(seq)
Run Code Online (Sandbox Code Playgroud)
或者,自Scala 2.10起,
implicit class SumTraversableOnce[T](val seq: TraversableOnce[T]) {
def sum[Res](f: T => Res)(implicit num: Numeric[Res]) = mySum(f, seq)(num)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11705 次 |
| 最近记录: |