разреженный список значений с использованием диапазонов
есть более строгий способ написания
listOf('a'..'z','A'..'Z').flatMap { it }
Идея здесь состоит в том, чтобы перебирать некоторые значения в диапазоне, например числа от 1 до 100, пропуская с 21 по 24
listOf(1..20, 25..100).flatMap { it }
Ответ 1
Вы можете пойти немного короче для списка, используя flatten() вместо flatMap():
listOf('a'..'z','A'..'Z').flatten()
или более короткая форма (из @Ilya) - использовать оператор plus()+ для Iterable (интерфейс, который реализует диапазоны). Каждая + сделает копию списка:
val validLetters = ('a'..'z') + ('A'..'Z')
val someNumbers = (1..20) + (25..100)
или пойти более ленивым, как Sequence (не уверен, что это имеет значение здесь вообще, чтобы быть более ленивым):
sequenceOf('a'..'z','A'..'Z').flatten()
Как вспомогательные функции
В Котлине люди обычно создают вспомогательную функцию, чтобы хорошо обернуть такие вещи; если вам посчастливилось повторно использовать этот код:
// helper functions
fun sparseListOf(vararg ranges: CharRange): List<Char> = ranges.flatMap { it }
fun sparseListOf(vararg ranges: IntRange): List<Int> = ranges.flatMap { it }
... и использование для этих помощников:
val validLetters = sparseListOf('a'..'z', 'A'..'Z')
val someNumbers = spareListOf(1..20, 25..100)
ПРИМЕЧАНИЕ: вспомогательные функции используют flatMap(), так как нет flatten() метода или расширения для Array<out XYZ> который является типом получил от vararg. Лямбда встроена настолько, что нет никакой реальной разницы в производительности.
Ответ 2
kotlin.Char.rangeTo возвращает CharRange который является реализацией CharProgression. CharProgression является подклассом Iterable а оператор "плюс" определяется на итерациях: Iterable<T>.plus