Assume that I have an array like 1 2 3 4 5
, I want to shift them to left by n rotation and get a new one.
For example the 2 rotation of the above array will result in 3 4 5 1 2
. I didn't found any extension function to do that.
Assume that I have an array like 1 2 3 4 5
, I want to shift them to left by n rotation and get a new one.
For example the 2 rotation of the above array will result in 3 4 5 1 2
. I didn't found any extension function to do that.
You can write your own extension function on Array<T>
fun <T> Array<T>.leftShift(d: Int): Array<T> {
val newList = this.copyOf()
var shift = d
if (shift > size) shift %= size
forEachIndexed { index, value ->
val newIndex = (index + (size - shift)) % size
newList[newIndex] = value
}
return newList
}
You can use built-in java Collections.rotate
method, but you need to convert your array to list firstly:
val arr = intArrayOf(1, 2, 3, 4, 5)
val list = arr.toList()
Collections.rotate(list, -2)
println(list.toIntArray().joinToString())
Outputs
3, 4, 5, 1, 2
I interpret "get a new one" to mean that the extension function should return a new instance, like so (boundary checks omitted) :
fun <T> Array<T>.shift(n: Int) =
let { sliceArray(n until size) + sliceArray(0 until n) }
Another extension function, by slicing the array in 2 parts left
and right
and reassembling it to right + left
:
fun <T> Array<T>.leftShift(d: Int) {
val n = d % this.size // just in case
if (n == 0) return // no need to shift
val left = this.copyOfRange(0, n)
val right = this.copyOfRange(n, this.size)
System.arraycopy(right, 0, this, 0, right.size)
System.arraycopy(left, 0, this, right.size, left.size)
}
so this:
val a = arrayOf(1, 2, 3, 4, 5, 6, 7)
a.leftShift(2)
a.forEach { print(" " + it) }
will print
3 4 5 6 7 1 2