Collections 如何在Kotlin中使用唯一的增量键对值进行分组?

Collections 如何在Kotlin中使用唯一的增量键对值进行分组?,collections,kotlin,Collections,Kotlin,例如,我有这样的清单: {{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} } fun subgroups(data: Map<Int, Str

例如,我有这样的清单:

{{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}
}
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
}
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")
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})
}
但我想将其分组如下:

{
   a: = {1,2,6,7,8},
   b: = {3,4,5}
}
{
   a1: = {1,2},
   b1: = {3,4,5},
   a2: = {6,7,8}
}
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
}
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")
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})
}

我应该使用什么Kotlin函数?

我想这是一个非常特殊的用例。一个不太实用的实现可能如下所示:

{
   a: = {1,2,6,7,8},
   b: = {3,4,5}
}
{
   a1: = {1,2},
   b1: = {3,4,5},
   a2: = {6,7,8}
}
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
}
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")
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})
}
fun子组(数据:Map):Map{
if(data.isEmpty())抛出IllegalArgumentException()
val counter=data.values.toSet().associateWithTo(mutableMapOf()){1}
var last=data.values.first()
val result=mutableMapOf()
data.forEach{k,v->
如果(v!=最后一个){
计数器[last]=计数器.getOrDefault(last,0)+1
last=v
}
“$v${counter[v]}”。让{key->
result[key]=result.getOrDefault(key,listOf())+k
}
}
返回结果
}
我希望这对您有用,因为有一个
列表(因为顺序很重要),如下所示:

{
   a: = {1,2,6,7,8},
   b: = {3,4,5}
}
{
   a1: = {1,2},
   b1: = {3,4,5},
   a2: = {6,7,8}
}
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
}
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")
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})
}
您可以这样做:

{
   a: = {1,2,6,7,8},
   b: = {3,4,5}
}
{
   a1: = {1,2},
   b1: = {3,4,5},
   a2: = {6,7,8}
}
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
}
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")
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})
}
fun groupCount(list:list):映射{
val countMap=mutableMapOf()
var currentStr=list.firstOrNull()?.second?:返回emptyMap()
return list.map{(键,值)->
如果(currentStr!=值){
currentStr=值
countMap[value]=((countMap[value]?:0)+1)
}
value+countMap.getOrPut(值,{1})的键
}.groupBy({it.second},{it.first})
}
最后,当你需要打开它时,Kotlin's会变得特别方便

[(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]}



如果你碰巧有一个
映射
,你可以调用
toList()
,然后把它传递给
groupCount

为什么
6
a2
而不是
a1
中?什么决定了您期望的映射中的键?@GuiSim My list包含具有相同值的元素子列表。每个子列表应使用自定义键(字符串值+增量id)分组。换句话说,如果我有下一组元素,并且已经添加了key
a
,那么它应该被视为新的key(
a2
,或者其他任何东西),您可能需要为此创建自己的实现;如果没有内置功能,它将无法使用。@Lester我们能为您提供帮助吗(参见答案):?是的,谢谢,我接受您的答案