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
相关产品推荐
相关产品推荐

