如何按两个字段对Kotlin列表对象分组并转换为PickingList列表?
正确按两个字段分组并转换为目标列表的方法
问题根源
你之前的groupBy({ it.runId }, { it.pickingId })用法错误,这个重载的第二个参数是将每个元素映射为分组后的元素值,而非第二个分组键。而groupingBy仅创建分组的中间容器,需要配合fold/reduce等操作才能生成实际分组结果,并非直接返回分组集合。
正确实现步骤
1. 用Pair作为双字段分组键
Kotlin的Pair是数据类,自动实现了equals()和hashCode(),可以直接作为groupBy的分组键,完美适配双字段分组需求:
val items: List<ItemDataDTO> = someItemRepository.getItemsForWarehouse("someWarehouseId") // 按runId和pickingId分组,得到键为Pair、值为对应ItemDataDTO列表的Map val groupedMap = items.groupBy { Pair(it.runId, it.pickingId) }
2. 转换为目标List
由于ItemDataDTO中的runId和pickingId是可空类型,而PickingList的对应字段为非空,需要先过滤掉包含null的分组,再转换为目标对象:
val pickingLists: List<PickingList> = groupedMap.mapNotNull { (key, items) -> val (runId, pickingId) = key // 仅保留runId和pickingId都非空的分组 if (runId != null && pickingId != null) { PickingList(runId, pickingId, items) } else { null } }
简化合并版
可以将两步逻辑合并为一行代码:
val pickingLists = items.groupBy { Pair(it.runId, it.pickingId) } .mapNotNull { (key, items) -> key.first?.let { runId -> key.second?.let { pickingId -> PickingList(runId, pickingId, items) } } }
可选方案:自定义分组键数据类
如果你不想用Pair,也可以自定义一个数据类作为分组键,效果完全一致:
data class GroupKey(val runId: String?, val pickingId: String?) val groupedMap = items.groupBy { GroupKey(it.runId, it.pickingId) }
内容的提问来源于stack exchange,提问作者hc0re
相关产品推荐
相关产品推荐

