将Map中的Map(key,Set [value])附加到Scala 2.11中的现有Key

时间:2019-07-05 14:01:08

标签: scala functional-programming

我试图将新值附加到现有键的Set(Values)上,但是它将替换现有值。

这是我的输入

val roads = Array(Array(0,1),Array(0,2),Array(1,2))

预期输出:

Map(0 -> Set(1,2),1 -> Set(2))

我的代码:

  val roads = Array(Array(0,1),Array(0,2),Array(1,2))
  var adjMatrix:Map[Int,Set[Int]] = Map()

  for(i <- 0 until roads.size; j <- 1 until roads(i).size){
    adjMatrix += (roads(i)(0) -> Set(roads(i)(j)))
  }

当我这样做

  adjMatrix.foreach(println)

我得到以下结果,因为有两个键的名称为0,它替换了第0个索引处的(0,1)元素

(1,Set(2))
(0,Set(2))

2 个答案:

答案 0 :(得分:5)

尝试

roads
  .groupBy(a => a(0))
  .map { case (key, value) => key -> (value.flatten.toSet - key) }

输出

Map(1 -> Set(2), 0 -> Set(1, 2))

答案 1 :(得分:3)

您可以做的是首先提取每个组的密钥。
然后,groupBy该密钥。
最后,加入所有值并将它们变成最终的 Set

(注意:我用 List 更改了 Array ,因为提取数组的tail是非常昂贵的操作。)

val roads = List(List(0,1),List(0,2),List(1,2))

val adjMatrix =
  roads.map {
    case x :: xs => x -> xs // This may fail if the list is empty!
  } groupBy {
    case (key, _) => key
  } map {
    case (key, values) => key -> values.flatMap(_._2).toSet // _._2 === case (_, values) => values.
  }

// adjMatrix: Map[Int, Set[Int]] = Map(1 -> Set(2), 0 -> Set(1, 2))

PS::我建议您至少升级到Scala 2.12