Android递归BaseModel模型中如何过滤number为7的对象?
解决递归BaseModel列表的过滤与子项保留问题
你的代码定义
BaseModel 数据类
data class BaseModel( val title: String, val number: Int, val items: List<BaseModel>? = null )
递归列表生成方法
fun generateModel(): List<BaseModel> { val childItem1 = BaseModel("child1", 1) val childItem2 = BaseModel("child2", 2) val childItem3 = BaseModel("child3", 3) val childItem4 = BaseModel("child4", 4) val childItem5 = BaseModel("child5", 5) val childItem6 = BaseModel("child6", 6) val childItem7 = BaseModel("child7", 7) val childItem8 = BaseModel("child8", 8) val childList1 = arrayListOf(childItem1, childItem2, childItem3) val childList2 = arrayListOf(childItem4, childItem5) val childList3 = arrayListOf(childItem6, childItem7, childItem8) val parentItem1 = BaseModel("parent1", 11, childList1) val parentItem2 = BaseModel("parent2", 22, childList2) val parentItem3 = BaseModel("parent3", 33, childList3) return arrayListOf(parentItem1, parentItem2, parentItem3) }
需求说明
要从生成的列表里筛选出包含number=7的子项的BaseModel对象,同时最终结果里该父对象的items只保留符合条件的子项,预期结果如下:
[ title: "parent3", number: 33, items: [ title: "child7", number: 7, items: null ] ]
实现方案
直接用filter只能筛选父对象,但没法处理子项的过滤;map可以转换对象,但要结合递归判断和子项过滤。可以分两步处理:
- 先筛选出所有包含目标子项的父对象
- 对筛选出的父对象,只保留其items里符合条件的子项(深层嵌套的子项也能递归处理)
完整代码
// 递归判断当前节点或其子节点是否包含number=7的项 fun BaseModel.hasTargetItem(): Boolean { if (number == 7) return true return items?.any { it.hasTargetItem() } ?: false } // 递归过滤子项,仅保留包含目标项的节点,同时处理深层嵌套 fun BaseModel.filterTargetChildren(): BaseModel { val filteredItems = items?.filter { it.hasTargetItem() }?.map { it.filterTargetChildren() } return copy(items = filteredItems.takeIf { it?.isNotEmpty() == true }) } // 主处理方法 fun getFilteredModels(models: List<BaseModel>): List<BaseModel> { return models .filter { it.hasTargetItem() } .map { it.filterTargetChildren() } }
使用示例
fun main() { val originalList = generateModel() val result = getFilteredModels(originalList) println(result) // 输出:[BaseModel(title=parent3, number=33, items=[BaseModel(title=child7, number=7, items=null)])] }
代码说明
hasTargetItem():递归检查当前节点或其所有子节点是否存在number=7的项,用来筛选符合条件的父对象。filterTargetChildren():递归过滤子项列表,只保留包含目标项的子节点,并且对这些子节点也做同样的过滤(适配深层嵌套场景),最后返回复制后的新对象,避免修改原数据。getFilteredModels():先筛选出包含目标子项的父对象,再对每个父对象过滤其子项,得到最终结果。
内容的提问来源于stack exchange,提问作者androidlover
相关产品推荐
相关产品推荐

