Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
You can’t perform that action at this time.