Last active
April 25, 2017 18:40
-
-
Save lameroid/b7164587249c146e126704c67464e41a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fun lsxUsage() { | |
val list = listOf(2, 3, 5, 7, 11, 13, 17, 19, 23, 29) | |
println(list[1..3]) // [3, 5, 7] | |
println(list[1 til 3]) // [3, 5] | |
println(list[4..1]) // [11, 7, 5, 3] | |
println(list[4 til 1]) // [11, 7, 5] | |
println(list[2..-1]) // [5, 7, 11, 13, 17, 19, 23, 29] | |
println(list[2 til -1]) // [5, 7, 11, 13, 17, 19, 23] | |
println(list[3..0 by 1]) // [7, 5, 3, 2] | |
println(list[3 til 0 by 1]) // [7, 5, 3] | |
println(list[-1..1 by 2]) // [29, 19, 13, 7, 3] | |
println(list[-1 til 1 by 2]) // [29, 19, 13, 7] | |
} | |
data class OpenRange(val first: Int, val last: Int) | |
// I spitted classes because `begin til end by step by step` is messy | |
data class Range(val first: Int, val last: Int, val step: Int = 1, val closed: Boolean) { | |
init { | |
if (step <= 0) throw IllegalArgumentException("Step must be positive, was: $step.") | |
} | |
} | |
infix fun Int.til(last: Int) = OpenRange(this, last) | |
// this function is extension because I wanted highlighting | |
infix fun OpenRange.by(step: Int) = Range(first, last, step, closed = false) | |
infix fun IntRange.by(step: Int) = Range(first, last, step, closed = true) | |
operator fun <T> List<T>.get(range: OpenRange): List<T> = this[range by 1] | |
operator fun <T> List<T>.get(range: IntRange): List<T> = this[range by 1] | |
operator fun <T> List<T>.get(range: Range): List<T> = | |
(range adaptTo size).map { get(it) } | |
private infix fun Int.adaptTo(size: Int) = this + if(this < 0) size else 0 | |
// this function is not member because I wanted it to be file private | |
private infix fun Range.adaptTo(size: Int): IntProgression { | |
val first = first adaptTo size | |
var last = last adaptTo size | |
if (!closed) when { | |
first == last -> return 1..0 // empty range | |
first < last -> last -= 1 | |
first > last -> last += 1 | |
} | |
return when { | |
first <= last -> first..last step step | |
else -> first downTo last step step | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment