gpt4 book ai didi

Kotlin 将 List>> 转换为 Multimap

转载 作者:行者123 更新时间:2023-12-05 01:53:55 25 4
gpt4 key购买 nike

我正在寻找一种转换成对列表的惯用方法,其中 Pair.first 是一个键,Pair.second 是一个值列表。这种过程方法有效,但我希望找到一种不需要直接创建可变列表的更惯用的方法。

val pairs: Pair<String, List<Int>>

val res = mutableMapOf<String, List<Int>>()
pairs.forEach {
res.getOrPut(it.first, ::mutableListOf).addAll(it.second)
}

这段代码可以像下面这样包装在一个扩展函数中,但它看起来不是很通用:

fun <K, V> List<Pair<K, Collection<V>>>.toMultimap(): Map<K, List<V>> {
var res = mutableMapOf<K, MutableList<V>>()
forEach {
res.getOrPut(it.first, ::mutableListOf).addAll(it.second)
}
return res
}

使用 pairs.toMap 不起作用,因为它用最后获胜的方法覆盖 map 键。 groupBy 的工作很接近,它在列表结构的列表中创建值的键。

val pairs2 = listOf(
Pair("a", listOf(1, 2, 3)),
Pair("b", listOf(6, 7)),
Pair("a", listOf(4, 5)),
Pair("b", listOf(8, 9)),
)

val res = pairs2.groupBy({ it.first }, { it.second })
println(res)

{a=[[1, 2, 3], [4, 5]], b=[[6, 7], [8, 9]]}

然后可以将映射展平,但这里的缺点是它非常低效,因为这会为每个键创建两倍的所需 HashMap 和列表(一个用于 groupby,另一个用于展平)。如果有

val res = pairs2.groupBy({ it.first }, { it.second }).mapValues { it.value.flatten() }
println(res)

{a=[1, 2, 3, 4, 5], b=[6, 7, 8, 9]}

看看是否有更好的方法来完成此转换。

最佳答案

而不是 groupBy,使用 groupingBy ,它会产生一个 Grouping。这是一个中间对象,您可以在其上执行各种折叠/减少操作。在你的情况下:

fun <K, V> List<Pair<K, Collection<V>>>.toMultimap() =
groupingBy { it.first }
.fold(emptyList<V>()) { acc, (_, new) -> acc + new }

如果您不喜欢 + 创建太多新列表,您可以这样做:

groupingBy { it.first }
.fold({ _, _ -> mutableListOf<V>() }) { _, acc, (_, new) ->
acc.addAll(new)
acc
}

关于Kotlin 将 List<Pair<K, Collection<V>>> 转换为 Multimap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70916919/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com