You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Kotlin按规则合并两个HumanValue列表生成规范列表?

Kotlin函数式风格合并HumanValue列表生成规范列表

我有两个HumanValue类型的列表如下:

val localList = listOf(
    HumanValue(id = "abc", gamesPlayed=7, gamesWon=4, removed=false),
    HumanValue(id = "abcd", gamesPlayed=1, gamesWon=0, removed=false),
    HumanValue(id = "abcde", gamesPlayed=6, gamesWon=3, removed=false),
    HumanValue(id = "abcdef", gamesPlayed=12, gamesWon=12, removed=false)
)

val remoteList = listOf(
    HumanValue(id = "abc", gamesPlayed=12, gamesWon=7, removed=false),
    HumanValue(id = "abcd", gamesPlayed=1, gamesWon=0, removed=false),
    HumanValue(id = "abcde", gamesPlayed=6, gamesWon=3, removed=true),
    HumanValue(id = "abcdef", gamesPlayed=12, gamesWon=12, removed=false),
    HumanValue(id = "abcdefg", gamesPlayed=0, gamesWon=0, removed=false)
)

需要生成一个规范列表,规则为:

  • 同一id的项,取gamesPlayed数值更高的作为最新规范项;
  • 项的默认状态为未移除,只要任意一个标记为已移除,则最终状态为已移除。

我当前的实现方式不够优雅,代码如下:

suspend fun compareDBs() {
    if ((localDeck.value?.size == remoteDeck.value?.size) && (localDeck.value?.toSet() == remoteDeck.value?.toSet())) { return }
    else {
        val diff1: MutableList<HumanValue> = mutableListOf(localDeck.value?.minus(arrayOf(remoteDeck).toSet())) as MutableList<HumanValue>
        val diff2 = remoteDeck.value?.minus(arrayOf(localDeck).toSet()) as MutableList<HumanValue>

        val listOfDifferences = mutableListOf<HumanValue>()
        listOfDifferences.addAll(diff1)
        listOfDifferences.addAll(diff2)

        listOfDifferences.forEach {diffValue ->
            val localVersion = localDeck.value?.filter { it.id == diffValue.id }
            val remoteVersion = remoteDeck.value?.filter { it.id == diffValue.id }
            
            if (!localVersion.isNullOrEmpty() && !remoteVersion.isNullOrEmpty()) {
                if (localVersion[0].gamesPlayed > remoteVersion[0].gamesPlayed) { localIsCanonical() }
                else { remoteIsCanonical() }
            }
            else {
                if (localVersion.isNullOrEmpty()) { remoteIsCanonical() }
                else if (remoteVersion.isNullOrEmpty()) { localIsCanonical() }
            }
        }
    }
}

想找更符合Kotlin风格的函数式实现,用map、groupBy等方法简化逻辑。


优化实现方案

核心思路

  1. 合并两个列表,按id分组,确保每个id的本地、远程项都在同一组内;
  2. 对每个分组,先选出gamesPlayed最大的项作为基础;
  3. 检查分组内是否存在removed=true的项,存在则将规范项的removed设为true;
  4. 收集所有分组的规范项,得到最终列表。

代码实现

// 假设已定义HumanValue数据类
data class HumanValue(
    val id: String,
    val gamesPlayed: Int,
    val gamesWon: Int,
    val removed: Boolean
)

fun generateCanonicalList(local: List<HumanValue>, remote: List<HumanValue>): List<HumanValue> {
    return (local + remote)
        .groupBy { it.id }
        .values
        .map { group ->
            val maxPlayedItem = group.maxByOrNull { it.gamesPlayed }!!
            val isRemoved = group.any { it.removed }
            maxPlayedItem.copy(removed = isRemoved)
        }
}

// 测试调用示例
fun main() {
    val canonicalList = generateCanonicalList(localList, remoteList)
    canonicalList.forEach { println(it) }
}

输出结果

HumanValue(id=abc, gamesPlayed=12, gamesWon=7, removed=false)
HumanValue(id=abcd, gamesPlayed=1, gamesWon=0, removed=false)
HumanValue(id=abcde, gamesPlayed=6, gamesWon=3, removed=true)
HumanValue(id=abcdef, gamesPlayed=12, gamesWon=12, removed=false)
HumanValue(id=abcdefg, gamesPlayed=0, gamesWon=0, removed=false)

优势说明

  • 完全采用Kotlin函数式API,逻辑清晰简洁,避免冗余循环和空值判断;
  • 时间复杂度为O(n)(n为两个列表总元素数),效率更高;
  • 代码可读性强,每一步操作直接对应规则,易于维护。

内容的提问来源于stack exchange,提问作者Paxana Non Grata

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 22:42:36