Reputation: 29
I have two Maps:
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....)
)
And I wanted to create a third Map by matching Map1 values to Map2 Keys,
Where Map1 keys will be the Key and Map2 values will be the value of this new third Map.
It would be like this
val myMap3 = Map(
testKey1 -> List(Value1, Value2, Value3....),
testKey2 -> List(Value4, Value5, Value6....),
testKey4 -> List(Value7, Value8, Value9....)
)
I am failed to iterate over the Map1 values which is a list and get the corresponding key of that value.
Upvotes: 0
Views: 1339
Reputation: 22840
You can get what you want by using mapValues
on the first Map to get each List of values' keys, and then use flatMap
on this lis to get the desired values.
Here is an example, please note the getOrElse
method, to ensure we always get a value, even if the key does not exists.
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)
// )
If you need to remove the keys with empty values you can filter after.
myMap3.filter { case (_, values) => values.nonEmpty }
If I want to create this myMap3 where the value will be myMap2's key and their respective value.
Given the values of myMap1
are a list of keys for myMap2
, I think what you really want is a 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())
// )
Again, you can filter empty values if you don't need them.
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))
// )
Upvotes: 2