例如,我有这样的列表:
{{1,"a"},{2,"a"},{3,"b"},{4,"b"},{5,"b"},{6,"a"},{7,"a"},{8,"a"}}
如果我使用Kotlin的groupBy { it.value }
,它将像这样:
{
a: = {1,2,6,7,8},
b: = {3,4,5}
}
但是我想这样分组:
{
a1: = {1,2},
b1: = {3,4,5},
a2: = {6,7,8}
}
我应该使用Kotlin的什么功能?
答案 0 :(得分:1)
我猜这是一个非常特殊的用例。一种功能不完全的实现可能看起来像这样:
fun subgroups(data: Map<Int, String>): Map<String, List<Int>> {
if (data.isEmpty()) throw IllegalArgumentException()
val counter = data.values.toSet().associateWithTo(mutableMapOf()){ 1 }
var last = data.values.first()
val result = mutableMapOf<String, List<Int>>()
data.forEach { k, v ->
if (v != last) {
counter[last] = counter.getOrDefault(last, 0) + 1
last = v
}
"$v${counter[v]}".let { key ->
result[key] = result.getOrDefault(key, listOf()) + k
}
}
return result
}
我希望这对您有用
答案 1 :(得分:1)
给出List
的{{1}}(因为顺序很重要),如下所示:
Pair<Int, String>
您可以执行以下操作:
val list = listOf(1 to "a", 2 to "a", 3 to "b", 4 to "b", 5 to "b", 6 to "a", 7 to "a", 8 to "a")
最后,当您需要转动Kotlin的groupBy时,它变得特别方便
[(1,a1),(2,a1),(3,b1),(4,b1),(5,b1),(6,a2),(7,a2),(8,a2 )]
对此:
{a1 = [1,2],b1 = [3,4,5],a2 = [6,7,8]}
如果碰巧有一个fun groupCount(list: List<Pair<Int, String>>): Map<String, List<Int>> {
val countMap = mutableMapOf<String, Int>()
var currentStr = list.firstOrNull()?.second ?: return emptyMap()
return list.map { (key, value) ->
if(currentStr != value) {
currentStr = value
countMap[value] = ((countMap[value] ?: 0) + 1)
}
key to value + countMap.getOrPut(value, {1})
}.groupBy ({it.second}, {it.first})
}
,则可以在将其传递给Map<Int, String>
之前先致电toList()
。