'sparse list of values using ranges
is there a more terse way of writing
listOf('a'..'z','A'..'Z').flatMap { it }
The idea here is to iterate over some values in a range, like the numbers from 1 through 100, skipping 21 through 24
listOf(1..20, 25..100).flatMap { it }
Solution 1:[1]
You can go slightly shorter for a list by using flatten() instead of flatMap():
listOf('a'..'z','A'..'Z').flatten()
or a shorter form (from @Ilya) is to use the plus() + operator of Iterable (an interface that ranges implement). Each + will make a copy of the list:
val validLetters = ('a'..'z') + ('A'..'Z')
val someNumbers = (1..20) + (25..100)
or go more lazy as a Sequence (not sure it matters here at all to be lazier):
sequenceOf('a'..'z','A'..'Z').flatten()
##As Helper Functions##
In Kotlin people typically create a helper function to wrap things like this up nicely; if you happen to re-use this code a lot:
// helper functions
fun sparseListOf(vararg ranges: CharRange): List<Char> = ranges.flatMap { it }
fun sparseListOf(vararg ranges: IntRange): List<Int> = ranges.flatMap { it }
...and the usage for those helpers:
val validLetters = sparseListOf('a'..'z', 'A'..'Z')
val someNumbers = spareListOf(1..20, 25..100)
NOTE: the helper functions use flatMap() since there is no flatten() method or extension for Array<out XYZ> which is the type received from the vararg. The lambda is inlined so likely there is no real difference in performance.
Solution 2:[2]
The kotlin.Char.rangeTo returns a CharRange that is an implementation of CharProgression. CharProgression is a subclass of Iterable and the plus operator is defined on iterables: Iterable<T>.plus
Yeilding a very simple looking and obvious
('a'..'z') + ('A'..'Z')
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | activedecay |
