我有一个映射[String,ListString],我想反转它。例如,如果我有像这样的东西
"1" -> List("a","b","c")
"2" -> List("a","j","k")
"3" -> List("a","c")
结果应该是
"a" -> List("1","2","3")
"b" -> List("1")
"c" -> List("1","3")
"j" -> List("2")
"k" -> List("2")
我试过了:
m.map(_.swap)
但它返回一个映射[ListString,字符串]:
List("a","b","c") -> "1"
List("a","j","k") -> "2"
List("a","c") -> "3"
发布于 2017-11-16 04:59:31
地图反转稍微复杂一点。
val m = Map("1" -> List("a","b","c")
,"2" -> List("a","j","k")
,"3" -> List("a","c"))
m flatten {case(k, vs) => vs.map((_, k))} groupBy (_._1) mapValues {_.map(_._2)}
//res0: Map[String,Iterable[String]] = Map(j -> List(2), a -> List(1, 2, 3), b -> List(1), c -> List(1, 3), k -> List(2))
将Map
展平为元组的集合。groupBy
将使用旧的值作为新的密钥创建一个新的Map
。然后通过删除key (以前的value)元素来解组值。
发布于 2018-08-08 23:13:45
一个不依赖于flatten
的奇怪隐式参数的替代方案,如requested by yishaiz
val m = Map(
"1" -> List("a","b","c"),
"2" -> List("a","j","k"),
"3" -> List("a","c"),
)
val res = (for ((digit, chars) <- m.toList; c <- chars) yield (c, digit))
.groupBy(_._1) // group by characters
.mapValues(_.unzip._2) // drop redundant digits from lists
res foreach println
提供:
(j,List(2))
(a,List(1, 2, 3))
(b,List(1))
(c,List(1, 3))
(k,List(2))
发布于 2019-06-05 03:44:37
可以使用简单的嵌套的for- respective来反转映射,使得值列表中的每个值都是反转映射中的键,并将相应的键作为它们的值
implicit class MapInverter[T] (map: Map[T, List[T]]) {
def invert: Map[T, T] = {
val result = collection.mutable.Map.empty[T, T]
for ((key, values) <- map) {
for (v <- values) {
result += (v -> key)
}
}
result.toMap
}
用法:
Map(10 -> List(3, 2), 20 -> List(16, 17, 18, 19)).invert
https://stackoverflow.com/questions/47317040
复制相似问题