通过压缩找到相应值的平均值

时间:2013-11-29 07:33:00

标签: scala coding-style

我的目标是创建一个列表,其中包含来自其他两个列表的相应元素的平均值。例如,给定列表

val a = List[Double](1, 2)
val b = List[Double](3, 4)

我想创建列表(2, 3)。我的麻烦并不是我找不到有效的策略,而是我找到了太多的策略,无法确定哪一个是最佳实践。这是我到目前为止所发现的。

// Strategy 1
a.zip(b).map(pair => (pair._1 + pair._2) / 2)

// Strategy 2
a.zip(b).map { case (an, bn) => (an + bn) / 2 }

// Strategy 3
(a, b).zipped.map((an, bn) => (an + bn) / 2)

// Strategy 4
(a, b).zipped.map(_ / 2 + _ / 2)
策略4对我来说似乎最干净,但它让我感到紧张,因为

(a, b).zipped.map((_ + _) / 2)

似乎非常相似,但却给出错误

error: missing parameter type for expanded function ((x$1, x$2) => x$1.$plus(x$2))

我真的不明白。

我理解人们可能不同意哪种解决方案最干净,但我是Scala的新手,我正在努力建立产生可读代码的良好习惯。

总结一下:您认为哪种策略最干净(可能包括我未提出的策略),为什么最后一个示例会出错?

1 个答案:

答案 0 :(得分:3)

正如你所看到的,这些是非常相似的方法,所以最终它是一个品味问题。请注意,变体1和2基本相同,变体2只使用模式匹配来将元组分开。

所以基本上你有(a zip b).map(a, b).zipped.map。现在您发现zipped变体更“干净”。从技术上讲,这会产生Tuple2Zipped,我个人认为应该不鼓励采用这种方法。虽然它允许您从一些更简单的语法中受益,即map使用Function2而不是Function1[Tuple2[...]],但此类型完全在常规Scala集合类型层次结构之外,因此更快或者稍后,当您尝试使用Tuple2Zipped做一些非平凡的事情时,您会遇到很多不一致。

因此,我强烈推荐使用中缀运算符编写更加对称的变量2:

(a zip b).map { case (an, bn) => (an + bn) / 2 }