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!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With