Andrew
Andrew

Reputation: 2157

How to put range of ints instead writing them one by one kotlin listOf

For example we have such array:

val listArr = listOf(1,2,3,4,5,6,7)

and finally we receive:

1,2,3,4,5,6,7

maybe it is possible to write something like that:

val listArr = listOf(1..7)

and receive similar result. Or it is impossible right now?

Upvotes: 0

Views: 567

Answers (2)

Adam Millerchip
Adam Millerchip

Reputation: 23091

RobCo's answer is correct and answers the question asked.

About the followup question you asked in the comment to his answer:

how we can use such solution in another list for example 1,2,3,4,5,6,12,34,35,36,37

You could write a new function that accepts ranges:

fun customListOf(vararg ranges: IntRange) = ranges.flatMap { it.toList() }

Then use it like this:

fun main() {
    val list = customListOf(1..6, 12..12, 34..37)
    println(list)
}

Output:

[1, 2, 3, 4, 5, 6, 12, 34, 35, 36, 37]

However, you need to pass a range even for a single value like 12..12 above.


If you wanted to be hacky, you could write a function that accepts a vararg range: Any, and use reflection to check the type at runtime. That would allow you to mix ranges and ints in the same call:

fun hackyCustomListOf(vararg rangeOrInt: Any) = rangeOrInt.flatMap {
    when (it) {
        is IntRange -> it.toList()
        is Int -> listOf(it)
        else -> throw IllegalArgumentException("Expected an IntRange or an Int, got ${it::class}")
    }
}

Usage:

fun main() {
    val list1 = hackyCustomListOf(1, 5, 12..15, 25, 99..102)
    println(list1)
    val list2 = hackyCustomListOf(1..3, "boom", 5.0)
    println(list2)
}

Output:

[1, 5, 12, 13, 14, 15, 25, 99, 100, 101, 102]
Exception in thread "main" java.lang.IllegalArgumentException: Expected an IntRange or an Int, got class kotlin.String
    at TestKt.hackyCustomListOf(test.kt:7)
    at TestKt.main(test.kt:14)
    at TestKt.main(test.kt)

This removes compile-time checks on the argument, so I don't think it's a good idea. Fun exercise, though.

Upvotes: 1

RobCo
RobCo

Reputation: 6495

You can use the IntRange.toList() function:

val list = (1..7).toList()

Ranges are automatically converted to lists when concatenating:

val combined = (1..6) + 12 + (34..37)
// [1, 2, 3, 4, 5, 6, 12, 34, 35, 36, 37] 

Upvotes: 5

Related Questions