首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Scala中获得两个列表的平方和?

如何在Scala中获得两个列表的平方和?
EN

Stack Overflow用户
提问于 2011-10-25 09:46:09
回答 3查看 1.6K关注 0票数 2

如果我有两个列表

代码语言:javascript
复制
val first = List(1, 2, 3)
val second = List(4, 5, 6)

我将如何获得以下内容?

代码语言:javascript
复制
(1-4)^2 + (2-5)^2 + (3-6)^2
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-10-25 09:57:42

zip、map和sum:

代码语言:javascript
复制
first.view.zip(second).map(t => t._1 - t._2).map(x => x*x).sum

  • 将两个列表的元素组合成一个元组
  • 视图用于延迟计算列表,以便不在两个调用

的地图之间构建结构

(编辑以将reduceLeft替换为sum)

看到评论后,我觉得我必须回来解释一下我的观点。基本上,视图将Traversable转换为类似迭代器的结构,因此在应用mapzip和其他一些方法时,不必创建多个中间结构。GenIteratableViewLike的类型成员提供了哪些操作具有特殊处理的含义。因此,通常情况下,如果您按顺序应用了一堆map、filter、drop、takeWhile,则可以使用视图来获得一些性能。经验法则是尽早应用view以最小化创建的中间List的数量,如果有必要,在最后使用force返回到List (或您正在使用的任何集合)。因此,丹尼尔的建议。

关于性能的事情是,在实践中,如果这是重要的,你必须做一个现实的检查。下面是一些数字(越低越好):

代码语言:javascript
复制
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

代码如下:

代码语言:javascript
复制
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 }
票数 12
EN

Stack Overflow用户

发布于 2011-10-25 11:46:32

通常,如果函数比较复杂,您可能希望定义一个函数,而不是应用多个映射。您可以将其作为帮助器方法来执行,也可以匿名内联。

代码语言:javascript
复制
def op(i: Int, j: Int) = { val m = i - j; m * m }

(first, second).zipped.map(op).sum

代码语言:javascript
复制
(first, second).zipped.map( (i, j) => { val m = i - j; m * m } ).sum

在这些情况下,zippedzip更方便一些,因为它可以映射到带有两个参数的函数,而不是必须在其上使用._1._2字段的单个元组。

票数 5
EN

Stack Overflow用户

发布于 2011-10-25 11:49:47

带左折叠:

代码语言:javascript
复制
(0 /: first.zip (second)) ((a, b) => a + (b._1 - b._2)*(b._1 - b._2))

从拉链开始。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7883827

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档