Wrong reduce result with IntRange

fun main() {
    val n = 5
    val X = listOf(1, 2, 3, 4, 5)
    
    val result = (0 until n).reduce { acc, i -> acc + X[i] }
    
    println("--> $result")
}

Why does this code results in 14?

It becomes clear when you print out the actual values:

fun main() {
    val n = 5
    val X = listOf(1, 2, 3, 4, 5)
    
    val result = (0 until n).reduce { acc, i -> 
            println("acc: $acc, i: $i, x: ${X[i]}")
            acc + X[i] 
    }
    
    println("--> $result")
}

Output:

acc: 0, i: 1, x: 2
acc: 2, i: 2, x: 3
acc: 5, i: 3, x: 4
acc: 9, i: 4, x: 5
--> 14

https://pl.kotl.in/BJGyVmySV

Yea. But why `i’ doesn’t point to 0 on the first iteration?

This is the normal behavior of reduce and is also documented. What you are looking for is fold.

(0 until n).fold(initial = 0) { acc , i -> acc + X[i] } 

Because then you couldn’t use the 0-element as the starting value for the accumulator.

1 Like

I think what you’r looking for is this:

val result = X.reduce { acc, i -> acc + i }
1 Like

At the first iteration of reduce the lambda is called with the initial value of acc equal to the first element and i equal to the second element. Therefore acc = 0, and i = 1.

1 Like

Thanks. That’s what I’m looking for.