How to combine two object lists by id and select non-null values in kotlin

Viewed 1574

I want to combine two object lists. Each object has a specific id. If the same object exists in two lists, I want to merge them. And if a value is null I want to get the non-null one. For example:

val list1 = listOf(
    Object(id = 1, hello, 100),
    Object(id = 2, null, 40)
)

val list2 = listOf(
    Object(id = 1, null, 100),
    Object(id = 2, test, 40),
    Object(id = 3, hi, 13)
)

The result I want to achieve is as follows:

val result = listOf(
    Object(id = 1, hello, 100),
    Object(id = 2, test, 40),
    Object(id = 3, hi, 13)
)

NOTE: if a value is not empty I know it is not different.

2 Answers
fun main() {
    val list1 = listOf(
        Obj(id = 1, "hello", 100),
        Obj(id = 2, null, 40)
    )

    val list2 = listOf(
        Obj(id = 1, null, 100),
        Obj(id = 2, "test", 40),
        Obj(id = 3, "hi", 13)
    )

    val result = (list1.asSequence() + list2)
        .groupingBy { it.id }
        .reduce { _, accumulator: Obj, element: Obj ->
            accumulator.copy(second = accumulator.second ?: element.second)
        }
        .values.toList()

    println(result)
}

data class Obj(val id: Int, val second: String?, val third: Int)

There can be 2 approaches to the problem, O(n^2) approach where you loop through both the lists and check for each object. Or O(n) approach where you waste some extra space by creating a mapping in one dictionary for your list and looping on one while checking in other.

Related