如何对scala中相同键的地图求和
How to sum a map of maps of same key in scala
我有以下地图的地图:
var map1 : mutable.Map[String, Map[String, Double]]
map1("U1" -> ("a"-> 2.1, "b"->3.21, "c"->7.1),
"U2" -> ("a"-> 3.1, "b"->12.1, "c"->1.4)
)
我想遍历这张地图并以我得到以下方式合并所有值:
finalMap = ("a"->5.2, "b"->15.22, "c"->8.5)
我遇到了 this 并为解决方案导入了 scalaz,但我不太清楚如何在可迭代值上使用 |+|
。
我正在使用以下代码:
finalMap : Map[String, Double]()
map1.values.foreach{ (valueMap : Map[String, Double]) =>
finalMap |+| valueMap
}
有关如何更正此问题的任何指示
首先,使用val
s和不可变数据结构。其次,查看如何初始化集合;网络上有很多很多例子。
val map1 = Map("U1" -> Map("a"-> 2.1, "b"->3.21, "c"->7.1),
"U2" -> Map("a"-> 3.1, "b"->12.1, "c"->1.4))
最后,您要做的是 reduce
将 values
中的所有 Map
合并为一个 Map
。你可以这样做:
val finalMap = map1.values.reduce(_ |+| _)
// finalMap: Map[String,Double] = Map(a -> 5.2, b -> 15.31, c -> 8.5)
如果您认为 map1
可能为空,请改用 fold
,这基本上是一个 reduce
,您可以在其中给出一个初始值:
map1.values.fold(Map.empty)(_ |+| _)
// res0: Map[String,Double] = Map(a -> 5.2, b -> 15.31, c -> 8.5)
val emptyMap = Map.empty[String, Map[String, Double]]
emptyMap.values.fold(Map.empty)(_ |+| _)
// res1: Map[String,Double] = Map()
补充dhg的回答:
首先,要在 Map[A, B]
上使用 |+|
,我们需要一个 Semigroup[B]
实例。在这种情况下 Semigroup[Double]
。但是 scalaz 本身不会给你这个实例,因为它不会遵循正确的 Semigroup
实例 (related scalaz issue) 的 rules/laws。
不用绝望,因为我们仍然可以从项目scalaz-outlaws(它似乎只支持scalaz 7。1.x)中获取一个实例。使用 Double
outlaw 实例,我们现在可以组合两个 Double
,同时忽略敦促我们不要使用 Monoid[Double]
因为它不遵守法律的弃用消息:
import scalaz.syntax.semigroup._
import scalaz.outlaws.std.double._
1.0 |+| 2.0
// <console>:18: warning: value doubleMonoid in trait DoubleOutlawInstances
// is deprecated: Monoid[Double] violates the associativity law
// 1.0 |+| 2.0
// ^
// res0: Double = 3.0
其次,我们可以通过隐式使用 Monoid[Double]
而不是直接使用 |+|
来使用 scalaz 简化 reduce
/ fold
。
import scalaz.std.map._
import scalaz.outlaws.std.double._
import scalaz.syntax.foldable._
val map = Map("U1" -> Map("a"-> 2.1, "b"->3.21, "c"->7.1),
"U2" -> Map("a"-> 3.1, "b"->12.1, "c"->1.4))
map.concatenate
// Map[String,Double] = Map(a -> 5.2, b -> 15.309999999999999, c -> 8.5)
map.concatenate
类似于
map.values.fold(Monoid[Map[String, Double]].zero)(_ |+| _)
我有以下地图的地图:
var map1 : mutable.Map[String, Map[String, Double]]
map1("U1" -> ("a"-> 2.1, "b"->3.21, "c"->7.1),
"U2" -> ("a"-> 3.1, "b"->12.1, "c"->1.4)
)
我想遍历这张地图并以我得到以下方式合并所有值:
finalMap = ("a"->5.2, "b"->15.22, "c"->8.5)
我遇到了 this 并为解决方案导入了 scalaz,但我不太清楚如何在可迭代值上使用 |+|
。
我正在使用以下代码:
finalMap : Map[String, Double]()
map1.values.foreach{ (valueMap : Map[String, Double]) =>
finalMap |+| valueMap
}
有关如何更正此问题的任何指示
首先,使用val
s和不可变数据结构。其次,查看如何初始化集合;网络上有很多很多例子。
val map1 = Map("U1" -> Map("a"-> 2.1, "b"->3.21, "c"->7.1),
"U2" -> Map("a"-> 3.1, "b"->12.1, "c"->1.4))
最后,您要做的是 reduce
将 values
中的所有 Map
合并为一个 Map
。你可以这样做:
val finalMap = map1.values.reduce(_ |+| _)
// finalMap: Map[String,Double] = Map(a -> 5.2, b -> 15.31, c -> 8.5)
如果您认为 map1
可能为空,请改用 fold
,这基本上是一个 reduce
,您可以在其中给出一个初始值:
map1.values.fold(Map.empty)(_ |+| _)
// res0: Map[String,Double] = Map(a -> 5.2, b -> 15.31, c -> 8.5)
val emptyMap = Map.empty[String, Map[String, Double]]
emptyMap.values.fold(Map.empty)(_ |+| _)
// res1: Map[String,Double] = Map()
补充dhg的回答:
首先,要在 Map[A, B]
上使用 |+|
,我们需要一个 Semigroup[B]
实例。在这种情况下 Semigroup[Double]
。但是 scalaz 本身不会给你这个实例,因为它不会遵循正确的 Semigroup
实例 (related scalaz issue) 的 rules/laws。
不用绝望,因为我们仍然可以从项目scalaz-outlaws(它似乎只支持scalaz 7。1.x)中获取一个实例。使用 Double
outlaw 实例,我们现在可以组合两个 Double
,同时忽略敦促我们不要使用 Monoid[Double]
因为它不遵守法律的弃用消息:
import scalaz.syntax.semigroup._
import scalaz.outlaws.std.double._
1.0 |+| 2.0
// <console>:18: warning: value doubleMonoid in trait DoubleOutlawInstances
// is deprecated: Monoid[Double] violates the associativity law
// 1.0 |+| 2.0
// ^
// res0: Double = 3.0
其次,我们可以通过隐式使用 Monoid[Double]
而不是直接使用 |+|
来使用 scalaz 简化 reduce
/ fold
。
import scalaz.std.map._
import scalaz.outlaws.std.double._
import scalaz.syntax.foldable._
val map = Map("U1" -> Map("a"-> 2.1, "b"->3.21, "c"->7.1),
"U2" -> Map("a"-> 3.1, "b"->12.1, "c"->1.4))
map.concatenate
// Map[String,Double] = Map(a -> 5.2, b -> 15.309999999999999, c -> 8.5)
map.concatenate
类似于
map.values.fold(Monoid[Map[String, Double]].zero)(_ |+| _)