如果我有两个清单
val first = List(1, 2, 3)
val second = List(4, 5, 6)
Run Code Online (Sandbox Code Playgroud)
我如何获得以下内容?
(1-4)^2 + (2-5)^2 + (3-6)^2
Run Code Online (Sandbox Code Playgroud)
huy*_*hjl 12
邮编,地图和总和:
first.view.zip(second).map(t => t._1 - t._2).map(x => x*x).sum
Run Code Online (Sandbox Code Playgroud)
(编辑替换reduceLeft的sum)
看到评论后,我觉得我必须回来解释一下观点.基本上是一个视图变成一个Traversable进样结构的迭代器,以使得多个中间结构不是必须时创建应用类似的方法做map,zip和其他一些.GenIteratableViewLike的类型成员可以了解哪些操作具有特殊处理.所以通常如果你有一堆map,filter,drop,takeWhile按顺序应用,你可以使用view来获得一些性能.经验法则是view尽早应用以最小化List创建的中间体数量,并在必要时使用force最终返回List(或您正在使用的任何集合).因此丹尼尔的建议.
关于表现的事情是,在实践中,如果这很重要,你必须做一个现实检查.这里有一些数字(越低越好):
no view List(62, 62, 62, 62, 63) sum: 311
view before zip List(32, 31, 15, 16, 31) sum: 125
view after zip List(31, 46, 46, 31, 31) sum: 185
iterator List(16, 16, 16, 16, 15) sum: 79
zipped List(62, 47, 62, 46, 47) sum: 264
Run Code Online (Sandbox Code Playgroud)
代码在这里:
import testing.Benchmark
def lots[T](n: Int, f: => T): T = if (n > 0) { f; lots(n - 1, f) } else f
def bench(n: Int, id: String)(block: => Unit) {
val times = (new testing.Benchmark {
def run() = lots(10000, block)
}).runBenchmark(n)
println(id + " " + times + " sum: " + times.sum)
}
val first = List(1, 2, 3)
val second = List(4, 5, 6)
bench(5, "no view") { first.zip(second).map(t => t._1 - t._2).map(x => x*x).sum }
bench(5, "view before zip") { first.view.zip(second).map(t => t._1 - t._2).map(x => x*x).sum }
bench(5, "view after zip") { first.zip(second).view.map(t => t._1 - t._2).map(x => x*x).sum }
bench(5, "iterator") { first.iterator.zip(second.iterator).map(t => t._1 - t._2).map(x => x*x).sum }
bench(5, "zipped") { (first, second).zipped.map((a,b) => a - b).map(x => x*x).sum }
Run Code Online (Sandbox Code Playgroud)
一般来说,如果函数复杂,您可能希望定义一个函数,而不是应用多个映射.您可以将此作为辅助方法,或匿名内联.
def op(i: Int, j: Int) = { val m = i - j; m * m }
(first, second).zipped.map(op).sum
Run Code Online (Sandbox Code Playgroud)
要么
(first, second).zipped.map( (i, j) => { val m = i - j; m * m } ).sum
Run Code Online (Sandbox Code Playgroud)
zipped比zip在这些情况下更方便一些,因为它可以映射到一个带有2个参数的函数,而不是一个必须使用._1和._2字段的单个元组.
| 归档时间: |
|
| 查看次数: |
1328 次 |
| 最近记录: |