首页 > 解决方案 > 按类属性压缩 2 个 kotlin 列表

问题描述

给定以下人员定义:

open class Person(val name: String, val age: Int)
object EmptyPerson:Person("", 0)

以及以下数据:

val left = listOf(Person("Tinky-winkey", 1), Person("lala", 2))
val right = listOf(Person("Dipsy", 3), Person("Tinky-winkey", 4))

是否可以根据 name 属性压缩leftright列表以产生:

val result = listOf(
        Pair(Person("Tinky-winkey", 1), Person("Tinky-winkey", 4)),
        Pair(Person("lala", 2), EmptyPerson),
        Pair(EmptyPerson, Person("Dipsy", 3))
    )

以将左侧元素保留在pair().

就像是left.zipByProperty {right, p->p.name}

也许 zip 不是正确的方法?

标签: kotlin

解决方案


zip除了它们在集合中的位置之外,不处理匹配项。

我认为这会做你所描述的。最好先创建地图以降低复杂性,除非这些列表总是非常短。

inline fun <T, K> zipBy(first: List<T>, second: List<T>, default: T, keySelector: (T)->K): List<Pair<T, T>> {
    val firstByKey = first.associateBy(keySelector)
    val secondByKey = second.associateBy(keySelector)
    return (firstByKey.keys + secondByKey.keys)
        .map { (firstByKey[it] ?: default) to (secondByKey[it] ?: default) }
}

用法:

val result = zipBy(left, right, EmptyPerson, Person::name)

推荐阅读