使用`aggregate`合并地图

时间:2014-08-20 08:23:33

标签: scala map parallel-processing aggregate scala-collections

对于任何给定的Map集合,例如,

val in = Array( Map("a" -> 1,  "b" -> 2),
                Map("a" -> 11, "c" -> 4),
                Map("b" -> 7,  "c" -> 10))

如何在aggregate上使用in.par以便将地图合并到

Map ( "a" -> 12, "b" -> 9, "c" -> 14 )

注意Map已经多次询问合并,但在并行集合上寻找aggregate的解决方案。

非常感谢

1 个答案:

答案 0 :(得分:1)

如何将合并应用为seqopcomboop

val in = Array(
  Map("a" -> 1,  "b" -> 2),
  Map("a" -> 11, "c" -> 4),
  Map("b" -> 7,  "c" -> 10)
)

def merge(m1: Map[String, Int], m2: Map[String, Int]): Map[String, Int] =
  m1 ++ m2.map { case (k, v) => k -> (v + m1.getOrElse(k, 0)) }

in.par.aggregate(Map[String, Int]())(merge, merge)

<强>更新

您传递给aggregate初始累加器值(空地图)和两个闭包 - seqopcomboop

并行序列在几个分区中分割,以便并行处理。通过将seqop连续应用于累加器和数组元素来处理每个分区。

def seqop(
    accumulator: Map[String, Int], 
    element: Map[String, Int]): Map[String, Int] = merge(accumulator, element)

seqop获取初始累加器值和第一个数组元素并合并它。接下来它需要先前的结果和下一个数组元素,依此类推,直到整个分区合并到一个地图中。

当每个分区在单独的地图中合并时,应通过应用comboop来组合这些地图。 comboop从第一个分区获取合并的映射,从第二个分区获取合并的映射并将它们合并在一起。接下来它需要先前的结果和第三个分区的映射,依此类推,直到所有内容都合并到一个映射中。这是aggregate的结果。

def comboop(
    m1: Map[String, Int], 
    m2: Map[String, Int]): Map[String, Int] = merge(m1, m2)

seqopcomboop是一样的巧合。一般来说,它们的逻辑和签名不同。