Skip to content

Instantly share code, notes, and snippets.

@abreslav
Last active December 15, 2015 14:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save abreslav/5277352 to your computer and use it in GitHub Desktop.
Save abreslav/5277352 to your computer and use it in GitHub Desktop.
/*
Play with this code at
[http://goo.gl/yPtkb](Kotlin Web Demo)
*/
import subsequence.*
fun main(args: Array<String>) {
// for strings
val s = "Hello"
println(s)
println(s[1..2]) // ranges are inclusive, so this prints "el"
println(s[2..LAST]) // LAST works for any string/list, this prints "llo"
println(s[2..LAST-1]) // This prints "ll"
println(s[FIRST..LAST])
println(s[FIRST..2])
// and the same for lists
val l = listOf(1, 2, 3, 4)
println(l)
println(l[1..2]) // [2, 3]
println(l[2..LAST]) // [2, 3, 4]
println(l[2..LAST-1]) // [2, 3]
println(l[FIRST..LAST])
println(l[FIRST..2])
}
package subsequence
fun String.get(range: Range<Int>): String {
return substring(range.start, range.end + 1)
}
fun String.get(range: Pair<SequencePosition, SequencePosition>): String {
return substring(
range.first.toIndex(size),
range.second.toIndex(size) + 1
)
}
fun <T> List<T>.get(range: Range<Int>): List<T> {
return subList(range.start, range.end + 1)
}
fun <T> List<T>.get(range: Pair<SequencePosition, SequencePosition>): List<T> {
return subList(
range.first.toIndex(size),
range.second.toIndex(size) + 1
)
}
trait SequencePosition {
fun toIndex(size: Int): Int
fun rangeTo(other: SequencePosition): Pair<SequencePosition, SequencePosition> {
return Pair(this, other)
}
}
class SequenceIndex(public val index: Int): SequencePosition {
override fun toIndex(size: Int): Int = index
}
fun SequencePosition.rangeTo(index: Int): Pair<SequencePosition, SequencePosition> {
return Pair(this, SequenceIndex(index))
}
fun Int.rangeTo(other: SequencePosition): Pair<SequencePosition, SequencePosition> {
return Pair(SequenceIndex(this), other)
}
val FIRST: SequencePosition = SequenceIndex(0)
val LAST = object : SequencePosition {
override fun toIndex(size: Int): Int = size - 1
}
// To be able to say LAST - 1
fun SequencePosition.minus(delta: Int): SequencePosition
= object : SequencePosition {
override fun toIndex(size: Int): Int {
this@minus.toIndex(size) - delta
}
}
@jonnyzzz
Copy link

This looks awesome!
It could be nice time have methods like take
first N from start or end
Skip N elements from start / end

You may replace last and first with global constant and avoid explicir size calculation

BTW. This would also let it work with Iterator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment