如何在groupBy的结果列表中获得独特的价值

时间:2019-05-02 11:25:19

标签: kotlin

我有如下的自定义视图,效果很好。

val list = listOf(Pair("A", 1), Pair("A", 2), Pair("A", 1), Pair("B", 5))
val map = list.groupBy ({ it.first }, {it.second})

我得到的结果是

map = {A = [1, 2, 1], B = [5]}

但是,我只想在列表中具有独特的价值,即

map = {A = [1, 2], B = [5]}

我该如何实现?

4 个答案:

答案 0 :(得分:3)

这可以完成工作:

val list = listOf(Pair("A", 1), Pair("A", 2), Pair("A", 1), Pair("B", 5))
val map = list.groupBy ({ it.first }, {it.second}).mapValues { it.value.distinct() }

答案 1 :(得分:2)

您可以先致电列表中的.distinct()。线对的平等定义为两个要素的平等。

所以打电话之后

val list = listOf(Pair("A", 1), Pair("A", 2), Pair("A", 1), Pair("B", 5)).distinct()

list将包含[(A, 1), (A, 2), (B, 5)]。然后,您可以使用.groupBy()

答案 2 :(得分:0)

使用Grouping / group-and-fold,您可能迟早会发现以下有趣的内容:

val map = list.groupingBy { it.first }
        .fold(mutableSetOf<Int>()) { acc, e ->
            acc.apply {
                add(e.second)
            }
        }

如果您不希望公开MutableSet(因为map的类型现在为Map<String, MutableSet<Int>>),您仍然可以设置{{1} }明确地,例如map

或者:如果您更频繁地需要这种功能,您甚至可能想要考虑自己类似于val map : Map<String, Set<Int>> = ...的扩展功能:

groupBy

然后您可以使用它类似于以下内容:

inline fun <T, K, V> Iterable<T>.groupByDistinctValues(keySelector: (T) -> K, valueTransform: (T) -> V): Map<K, Set<V>> = groupByDistinctValuesTo(LinkedHashMap(), keySelector, valueTransform)
inline fun <T, K, V, M : MutableMap<in K, MutableSet<V>>> Iterable<T>.groupByDistinctValuesTo(destination: M, keySelector: (T) -> K, valueTransform: (T) -> V): M {
    for (element in this) {
        val key = keySelector(element)
        val list = destination.getOrPut(key) { mutableSetOf() }
        list.add(valueTransform(element))
    }
    return destination
}

答案 3 :(得分:0)

您还可以使用.single()来验证您没有重复

val list = listOf(Pair("A", 1), Pair("A", 2), Pair("A", 1), Pair("B", 5))
val map = list.groupBy ({ it.first }, {it.second}).mapValues { it.value.single() }