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

Kotlin中如何更新parentList中的childList嵌套子列表

Kotlin 列表匹配替换子项实现方案

基础数据结构

data class Skill(
    val id: Int,
    val name: String,
    val imageUrl: String? = null,
    val children: List<SkillChild>? = null,
) {
    data class SkillChild(
        val id: Int,
        val name: String,
        val imageUrl: String? = null,
        val note: Int? = null,
    )
}

输入与需求

持有数据

  • 完整父列表:元素为Skill类型的列表,每个父项可携带children子项列表
  • 待更新子列表:元素为Skill.SkillChild类型的列表,存储需要更新的子项数据

实现目标

遍历父列表所有Skill对象,对每个父项的children子列表做更新:

  • 子项id与待更新列表中id匹配的,替换为待更新列表中的对应对象
  • 未匹配到id的原有子项完整保留
  • 最终返回结构与原父列表一致的更新后列表

示例参考

示例输入

val skills = listOf<Skill>(
    Skill(
        id = 1,
        name = "skillName",
        imageUrl = null,
        children = listOf<Skill.SkillChild>(
            Skill.SkillChild(
                id = 45,
                name = "skillChildName",
                imageUrl = null,
                note = null
            ),
            Skill.SkillChild(
                id = 46,
                name = "skillChildName",
                imageUrl = null,
                note = null
            ),
            Skill.SkillChild(
                id = 47,
                name = "skillChildName",
                imageUrl = null,
                note = null
            ),
        )
    )
)

val skillChildren = listOf<Skill.SkillChild>(
    Skill.SkillChild(
        id = 45,
        name = "skillChildName",
        imageUrl = null,
        note = 2
    ),
    Skill.SkillChild(
        id = 46,
        name = "skillChildName",
        imageUrl = null,
        note = 3
    ),
)

预期输出

val result = listOf<Skill>(
    Skill(
        id = 1,
        name = "skillName",
        imageUrl = null,
        children = listOf<Skill.SkillChild>(
            Skill.SkillChild(
                id = 45,
                name = "skillChildName",
                imageUrl = null,
                note = 2
            ),
            Skill.SkillChild(
                id = 46,
                name = "skillChildName",
                imageUrl = null,
                note = 3
            ),
            Skill.SkillChild(
                id = 47,
                name = "skillChildName",
                imageUrl = null,
                note = null
            ),
        )
    )
)

实现代码

优先将待更新子列表转为id到对象的映射表,避免重复遍历查找,性能更优:

fun updateSkillChildren(
    originalSkills: List<Skill>,
    updateChildren: List<Skill.SkillChild>
): List<Skill> {
    // 构建待更新子项的id索引,实现O(1)时间复杂度的匹配查找
    val updateMap = updateChildren.associateBy { it.id }
    return originalSkills.map { skill ->
        // 父项无children时直接返回原对象,无需处理
        val childList = skill.children ?: return@map skill
        // 逐个子项匹配,匹配到更新项则替换,否则保留原项
        val newChildList = childList.map { child ->
            updateMap[child.id] ?: child
        }
        // 利用data class的copy方法生成更新后的父对象,不修改原始数据
        skill.copy(children = newChildList)
    }
}

调用方式

// 直接传入原始父列表和待更新子列表即可得到结果
val result = updateSkillChildren(skills, skillChildren)

逻辑说明

  • 全程使用不可变集合操作,不会修改原始输入列表,无副作用
  • 自动处理children为null的边界场景,不会触发空指针
  • 待更新列表中存在的多余id(父列表无对应子项)会被自动忽略,不会额外插入到子列表中
  • 支持父列表包含任意多个Skill对象的场景,无数量限制

内容的提问来源于stack exchange,提问作者MakiX

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 21:24:30