Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin combining 'N' lists together by summing each element

I'm attempting to combine N lists together by summing each individual element together and outputting one final list with the result. Here's a visualization:

List 1: { 1, 2, 3 }
List 2: { 4, 5, 6 }
List 3: { 7, 8, 9 }
...
List N: { X, X, X }

If we combined the first three, the output would be:

List Result: { 12, 15, 18 }

I'd like to continue summing the elements at each index, cleanly, inline, with optimal performance.

I know the zip operator would help here (easy enough to do list1.zip(list2) and add pair.first and pair.second) but it doesn't handle more than one list.

I educated myself on the Kotlin collection operations to try to find a solution - I looked into using fold, reduce, flatMap, zip, groupBy, and possibly transforming the List into a sequence to take advantage of the each-element aspect. But I can't seem to find a clean way to chain these operations together for a satisfying result.

ADDITIONAL INFO:

What I have now is an extension method called padStart (hidden for brevity) to help ensure all my nested lists are the same length, and then I'm clumsily creating a temporary list that I'm adding values to as I iterate:

myNestedLists
    .run {
        // Calculate largest list size of 'n' lists
        val largestSize = map { it.size }.max() ?: 0 
        // Pad lists with zeroes if size < largestSize
        map { it.padStart(largestSize, 0.0) }
    }
    .run {
        // Create temporary list, add all of the first elements to it
        val combinedList: MutableList<Double> = mutableListOf()

        combinedList.addAll(this.first())

        // Now, for each nested list, add each individual element with the combined value at combinedList[index]
        drop(1).forEach {
            it.forEachIndexed { index, value ->
                combinedList[index] += value
            }
        }

        // Return the final result
        combinedList
    }

This solution works, but it's hard to read and not very clean. I'm looking for a better one!

like image 677
0xMatthewGroves Avatar asked Oct 24 '25 12:10

0xMatthewGroves


1 Answers

Functional and straight forward:

lists.maxBy { it.size }!!.indices
     .map { index ->
        lists.mapNotNull { it.getOrNull(index) }.sum()
     }

If you're concerned about performance, the compiler will optimise it anyways.

EDIT:

If the number of lists is very big or the values are fetched by a service, you could use coroutines inside the map operation.

like image 86
Neo Avatar answered Oct 27 '25 03:10

Neo