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

Kotlin中如何按name属性过滤嵌套对象列表?

解决Kotlin中嵌套列表的过滤问题

你应该是想过滤CategoryModel列表,让每个返回的CategoryModel只保留符合指定name子串的CollectionModel,同时得到处理后的完整CategoryModel列表对吧?你的原始代码问题在于,只是把整个原CategoryModel加入结果,但没有对内部的collections做过滤,所以才会出现"有两个元素时全部保留"的情况。

下面给你两种符合需求的实现方式:


方法一:Map + Filter(最直观易读)

这个方法分两步处理:

  1. 给每个CategoryModel生成副本,将它的collections替换为过滤后符合条件的子列表
  2. (可选)过滤掉那些内部collections为空的CategoryModel,避免保留没有有效内容的分类
// 注意:capitalize()已被弃用,推荐用replaceFirstChar实现首字母大写
val textToSearchCapitalized = textToSearch.replaceFirstChar { it.uppercase() }

val filteredCategories = collection.map { category ->
    category.copy(
        collections = category.collections.filter { collectionModel ->
            collectionModel.name.contains(textToSearchCapitalized)
        }
    )
}.filter { it.collections.isNotEmpty() } // 这一步可选,根据需求决定是否保留空分类

为什么你的原始代码达不到预期?

你原来的循环逻辑是:只要找到一个符合条件的CollectionModel,就把整个原CategoryModel加入结果列表,但这个CategoryModel的collections还是原始的完整列表,并没有过滤掉不符合的元素,所以才会保留所有CollectionModel。

为什么reduce会报错?

reduce函数要求累积器的类型和当前元素的类型必须一致,你在代码里尝试把CategoryModel和List<CollectionModel>混合使用,类型不匹配,自然会编译报错。reduce更适合做累加、合并这类操作,并不适用于这种嵌套过滤的场景。


方法二:使用序列(Sequence)优化性能(数据量大时推荐)

如果你的列表数据量较大,可以用asSequence()来避免创建过多中间列表,提升处理性能:

val textToSearchCapitalized = textToSearch.replaceFirstChar { it.uppercase() }

val filteredCategories = collection.asSequence()
    .map { category ->
        category.copy(
            collections = category.collections.filter { it.name.contains(textToSearchCapitalized) }
        )
    }
    .filter { it.collections.isNotEmpty() }
    .toList()

内容的提问来源于stack exchange,提问作者S.P.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 09:42:32