Last active
December 15, 2015 14:49
-
-
Save abreslav/5277352 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
/* | |
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]) | |
} |
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
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 { | |
[email protected](size) - delta | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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