首页 > 解决方案 > Scala 将 Map 值与另一个 Map 键进行比较

问题描述

我有两个地图:

val myMap1 = Map(
    testKey1 -> List(testValue1, testValue2, testValue3....), 
    testKey2 -> List(testValue4, testValue5, testValue6....),
    testKey3 -> List(testValue7, testValue8, testValue9....)     
    testKey4 -> List(testValue10, testValue11, testValue12....)     
)

val myMap2 = Map(
        testValue1 -> List(Value1, Value2, Value3....), 
        testValue5 -> List(Value4, Value5, Value6....),
        testValue10 -> List(Value7, Value8, Value9....)
    )

我想通过将 Map1 值与 Map2 键匹配来创建第三个 Map,

其中 Map1 键将是键,Map2 值将是这个新的第三个 Map 的值。

会是这样

val myMap3 = Map(
        testKey1 -> List(Value1, Value2, Value3....), 
        testKey2 -> List(Value4, Value5, Value6....),
        testKey4 -> List(Value7, Value8, Value9....)
    )

我无法遍历作为列表的 Map1 值并获取该值的相应键。

标签: scala

解决方案


您可以通过mapValues在第一个Map上使用来获取每个值的键列表,然后flatMap在此 lis 上使用来获取所需的值,从而获得所需的内容。
这是一个例子,请注意getOrElse方法,以确保我们总是得到一个值,即使键不存在。

val myMap1 = Map(
  "testKey1" -> List("testValue1", "testValue2", "testValue3"), 
  "testKey2" -> List("testValue4", "testValue5", "testValue6"),
  "testKey3" -> List("testValue7", "testValue8", "testValue9"),
  "testKey4" -> List("testValue10", "testValue11", "testValue12")     
)

val myMap2 = Map(
  "testValue1" -> List(1, 2, 3), 
  "testValue2" -> List(5), 
  "testValue5" -> List(4, 5, 6),
  "testValue10" -> List(7, 8, 9)
)

val myMap3 = myMap1.mapValues {
  valuesList => valuesList.flatMap {
    valueKey => myMap2.getOrElse(valueKey, List.empty[Int])
  }
}

// myMap3: Map[String, List[Int]] = Map(
//   testKey1 -> List(1, 2, 3, 5),
//   testKey2 -> List(4, 5, 6),
//   testKey3 -> List(),
//   testKey4 -> List(7, 8, 9)
// )

如果您需要删除具有空值的键,您可以进行过滤。
myMap3.filter { case (_, values) => values.nonEmpty }

编辑

如果我想创建这个 myMap3,其中的值将是 myMap2 的键和它们各自的值。

鉴于 的值myMap1是 的列表myMap2,我认为您真正想要的是Map[String, Map[String, List[A]].

val myMap4 = myMap1.mapValues {
  valuesList => valuesList.map {
    valueKey => valueKey -> myMap2.getOrElse(valueKey, List.empty[Int])
  }.toMap
}

// myMap4: Map[String, Map[String, List[Int]]] = Map(
//   testKey1 -> Map(testValue1 -> List(1, 2, 3), testValue2 -> List(5), testValue3 -> List()),
//   testKey2 -> Map(testValue4 -> List(), testValue5 -> List(4, 5, 6), testValue6 -> List()),
//   testKey3 -> Map(testValue7 -> List(), testValue8 -> List(), testValue9 -> List()),
//   testKey4 -> Map(testValue10 -> List(7, 8, 9), testValue11 -> List(), testValue12 -> List())
// )

同样,如果不需要它们,您可以过滤空值。

val myMap5 = myMap1.mapValues {
  valuesList => valuesList.flatMap { // here we use flatMap, to filter any None.
    valueKey => myMap2.get(valueKey).map(values => valueKey -> values)
  }.toMap
} filter {
  case (_, values) => values.nonEmpty
}

// myMap5: Map[String, Map[String, List[Int]]] = Map(
//   testKey1 -> Map(testValue1 -> List(1, 2, 3), testValue2 -> List(5)),
//   testKey2 -> Map(testValue5 -> List(4, 5, 6)),
//   testKey4 -> Map(testValue10 -> List(7, 8, 9))
// )

推荐阅读