Is there a simple function to get an element with its index counting from the end in a Kotlin Array, List, or String? In other words, is there a Kotlin equivalent of negative index slicing in Python?
Is there a simple function to get an element with its index counting from the end in a Kotlin Array, List, or String? In other words, is there a Kotlin equivalent of negative index slicing in Python?
There is no direct function for slicing, but one can write an user defined function or easily simulate using reversed function, that works with string, lists and arrays.
Strings In Python
pyString = 'Python'
sObject = slice(-1, -4, -1)
print(pyString[sObject]) # output: noh
Strings In Kotlin
val pyString = "Python"
val sObject = pyString.reversed().substring(0, 3).reversed() // index 3 excluded
println(pyString) // output: noh
List(or Arrays) in Kotlin
var py = arrayOf(1, 2, 3, 4, 5, 6, 7, 8)
var sObject = py.reversed().slice(0..2).reversed()
println(sObject)
However you can do method or function overload, using this as implicit object
For instance, you can program reverse substring, but here you cannot use negative numbers, because we need a different parameters profile regarding to the original method:
fun String.substring(a: Int, b: Int = 0, rev: Boolean): String {
if (rev == true)
if (b == 0)
return this.substring(0, this.length - a)
else
return this.substring(this.length - b, this.length - a)
else
if (b == 0)
return this.substring(a)
else
return this.substring(a, b)
}
So "whale".substring(0,2,true) is "le"
You can use similar technique to extend slice method.
I implemented a function similar to python's slicing mechanism
import kotlin.math.abs
fun String.substring(startingIndex: Int, endingIndex: Int, step: Int=1): String {
var start = startingIndex
var end = endingIndex
var string = this
if (start < 0) {
start = string.length + start
}
if (end < 0) {
end = string.length + end
}
if (step < 0) {
string = string.reversed()
}
if (start >= string.length) {
throw Exception("Index out of bounds.")
}
var outString = ""
for ((index, character) in string.withIndex()) {
if (index % abs(step) == 0) {
if (index >= start && index <= end) {
outString += character
}
}
}
return outString
}
Can be used like this:
println("This is some text.".substring(8, -6)) // some
There is but on problem with my function, it is that a negative step messes it up if you also use negative indexes.
These answers are quite complicated. If you just want to use a negative index, all you have to do is
exampleList[exampleList.lastIndex - exampleIndex] which will (basically) do the same as exampleList[-exampleindex] in python.
So for example you would do:
fun main(args: Array<String>) {
val exampleList = mutableListOf<Int>(1, 2, 3, 4, 5)
//Now we want exampleList[-1] or 4. I know in python it would be writen as exampleList[-2], but don't worry about that!
println(exampleList[exampleList.lastIndex - 1])
}
the lastIndex parameter is the key thing to remember.