Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sparse list of values using ranges

Tags:

kotlin

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 }
like image 936
activedecay Avatar asked Jan 19 '16 15:01

activedecay


2 Answers

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.

like image 169
7 revs Avatar answered Nov 18 '22 19:11

7 revs


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')
like image 29
activedecay Avatar answered Nov 18 '22 17:11

activedecay