How to combine two data class according to the sam...
# announcements
s
How to combine two data class according to the same id field? for example
Copy code
data class DataA(
    val id: String,
    val fieldA: Int
)

data class DataB(
    val id: String,
    val fieldB: String
)

data class DataC(
    val id: String,
    val fieldA: Int,
    val fieldB: String
)

fun main() {
    val listA = listOf(
        DataA("2", 2),
        DataA("1", 1),
        DataA("3", 3)
    )

    val listB = listOf(
        DataB("3", "C")
        DataB("1", "A"),
        DataB("2", "B"),
    )

    val listC = doSomeMagic(listA, listB)

    print(listC) 
    // result: [DataC(id=1, fieldA=1, fieldB=A), DataC(id=2, fieldA=2, fieldB=B), DataC(id=3, fieldA=3, fieldB=C)]
}
I could do it with sort and zip. Any better solution?
a
A bit ugly, but doable with a map
Copy code
fun doSomeMagic(l1: List<DataA>, l2: List<DataB>): List<DataC> {
    val m1 = l1.groupBy { it.id }.mapValues { it.value[0] }
    return l2.map { DataC(it.id, m1[it.id]?.fieldA!!, it.fieldB)}
}
👀 1
a
Copy code
fun doSomeMagic(listA: List<DataA>, listB: List<DataB>): List<DataC> =
    listA.map { a -> DataC(a.id, a.fieldA, listB.first { it.id == a.id }.fieldB) }
Obviously if data is large enough
>1000
, sorting listB may help, by making complexity O(nlogn) compared to O(n^2).
n
If you just turn one of the lists into a map first the whole thing is O(N)
a
How does that work 👀
Oh hashtable 😅
n
Copy code
val listC = listA.associate { it.id to it }.run {
    listB.map { DataC(it.id, getValue(it).fieldA, it.fieldB) }
}
☝️ 1
2
It's probably both the most concise and the fastest for large datasets, for small/medium datasets sort is likely to be faster