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

如何用Kotlin解构声明在单次集合遍历中获取多个属性列表?

Kotlin 单次遍历提取集合多属性的实现方案

问题场景

现有业务场景如下:

data class Person(val name: String, val age: String, val color: String)
val persons = listOf(Person("john", "20", "green"), Person("Mary", "20", "blue"))

// 现有实现问题:
// 1. 调用3次map需遍历3次集合
val names = persons.map {it.name}
val ages = persons.map {it.age}
val colors = persons.map {it.color}

// 2. unzip仅支持单次遍历提取2个属性
val personsMap = persons.map { it.name to it.age }
val (names2, ages2) = personsMap.unzip()

// 需求:无需手动写forEach往列表追加元素,单次遍历同时提取3个属性,支持解构语法赋值
// val (names, ages, colors) = 单次遍历逻辑

实现方案

  • 方案1:用标准库原生fold函数实现,无需额外自定义逻辑
val (names, ages, colors) = persons.fold(
    Triple(mutableListOf<String>(), mutableListOf<String>(), mutableListOf<String>())
) { acc, person ->
    acc.first.add(person.name)
    acc.second.add(person.age)
    acc.third.add(person.color)
    acc
}

说明:fold 函数会在单次遍历中完成所有元素的聚合,最终返回的Triple直接支持解构,代码写法简洁,适合临时单次使用的场景。

  • 方案2:自定义通用unzip3扩展函数,适合高频复用场景
    首先定义全局通用扩展:
/**
 * 三属性解压扩展,逻辑与原生unzip对齐,单次遍历返回三个独立列表
 */
fun <T, A, B, C> Iterable<T>.unzip3(transform: (T) -> Triple<A, B, C>): Triple<List<A>, List<B>, List<C>> {
    val listA = mutableListOf<A>()
    val listB = mutableListOf<B>()
    val listC = mutableListOf<C>()
    for (item in this) {
        val (a, b, c) = transform(item)
        listA.add(a)
        listB.add(b)
        listC.add(c)
    }
    return Triple(listA.toList(), listB.toList(), listC.toList())
}

业务侧调用方式:

val (names, ages, colors) = persons.unzip3 { Triple(it.name, it.age, it.color) }

说明:扩展函数封装后调用逻辑和原生unzip保持一致,无冗余代码,适合项目中多处需要多属性提取的场景。

  • 方案3:使用kotlinx.collections.immutable库自带的unzip3实现
    如果项目已经引入了kotlinx不可变集合依赖,可直接使用库中提供的unzip3扩展,用法和上述自定义扩展完全一致,无需自行实现扩展逻辑。

内容的提问来源于stack exchange,提问作者En Hui Lim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 17:45:03