我有一个下面的Kotlin映射,我想反转该映射,对于重复的新密钥,该值将附加到列表中。
val map = Map(1 to 111, 2 to 222, 3 to 111)
转换后,结果图为
Map(111 to List(1,3), 222 to 2)
PS:我确实通过创建可变映射并迭代现有映射来制定出一种实现方法。但我更多地寻找一种不变的方法。
答案 0 :(得分:2)
您可以通过每个条目的值选择键将地图条目分组:
val map = mapOf(1 to 111, 2 to 222, 3 to 111)
val reversed = map.entries.groupBy({ it.value }, { it.key })
println(reversed) // prints: {111=[1, 3], 222=[2]}
答案 1 :(得分:1)
使用groupingBy
,更重要的是,使用aggregate
,这是不使用可变集合的一种简洁方法:
val map: Map<Int, Int> = mapOf(1 to 111, 2 to 222, 3 to 111)
val result: Map<Int, List<Int>> = map.entries
.groupingBy { it.value }
.aggregate { key: Int, accumulator: List<Int>?, element: Map.Entry<Int, Int>, first: Boolean ->
if (first) {
listOf(element.key)
} else {
accumulator!! + element.key
}
}
您还可以忽略first
参数,并使用空值处理来确定是否已经有累加器,当然,在两种情况下,您都无需显式键入参数:
val result: Map<Int, List<Int>> = map.entries
.groupingBy { it.value }
.aggregate { key, accumulator, element, first ->
accumulator?.plus(element.key) ?: listOf(element.key)
}
答案 2 :(得分:0)
您应该可以执行以下操作:
fun reverse(map: Map<Int, Int>): Map<Int, List<Int>> {
val mm = mutableMapOf<Int, List<Int>>()
map.forEach { k, v -> mm[v] = mm.getOrDefault(v, listOf()) + k }
return mm
}
它将为您提供所有地图值的列表,但确实会颠倒地图。