Get List size while constructing List

Hi, here somewhat of a trivial question. Often I construct lists with a fixed size and each element needs access to the size of the list. For example:

val angles = List(5) { 2 * 3.14159 * it / 5; }

In this case, the value 5 appears twice and if I change one, I should remember to change the other.
One solution is to use another variable to specify the length:

val angleCount = 5
val angles = List(angleCount) { 2 * 3.14159 * it / angleCount; }

This gets rid of the duplication, but makes the code longer and does not look great if angles is a property in a class. Now the class has a variable angleCount that I only need in the next line but it’s available in the whole class.

It came to my mind that maybe Kotlin could provide some kind of size variable that is available inside the loop:

val angles = List(5) { 2 * 3.14159 * it / listSize; } // pseudocode

Has anyone thought about this? Which approach would you use?

In some cases I’ve used helpers like these:

inline fun doubleRepeat(steps: Int, from: Double = 0.0, to: Double = 1.0,
                        action: (Double) -> Unit) {
    for (index in 0 until steps) {
        action(from + (to - from) * index / (steps - 1))
    }
}

inline fun loopRepeat(steps: Int, from: Double = 0.0, to: Double = 1.0,
                      action: (Double) -> Unit) {
    for (index in 0 until steps) {
        action(from + (to - from) * index / steps)
    }
}

which let me write this:

loopRepeat(5, to = 360.0) { doSomethingWithAngle(it) }

But in this case I miss the index, and it’s only a substitute for repeat, not for List.

1 Like
inline fun <T> buildListWithSize(size: Int, block (index: Int, size: Int) -> T): List<T> = List(size){ block(it, size)}
2 Likes

Thank you! :slight_smile:

There was a : missing, otherwise works great:

inline fun <T> buildListWithSize(
  size: Int, block: (index: Int, size: Int) -> T): List<T> = 
    List(size) { block(it, size) }
fun main() {
    val l = buildListWithSize(5) { i, sz -> i.toDouble() / sz }
    println(l)
}
// [0.0, 0.2, 0.4, 0.6, 0.8]