I was wondering what was the most efficient way to rotate a JavaScript array.
I came up with this solution, where a positive n
rotates the array to the
This function is a little faster than the accepted answer for small arrays but MUCH faster for large arrays. This function also allows for an arbitrary number of rotations greater than the length of the array, which is a limitation of the original function.
Lastly, the accepted answer rotates the opposite direction as described.
const rotateForEach = (a, n) => {
const l = a.length;
a.slice(0, -n % l).forEach(item => a.push( item ));
return a.splice(n % l > 0 ? (-n % l) : l + (-n % l));
}
And the functional equivalent (which seems to also have some performance benefits):
const rotateReduce = (arr, n) => {
const l = arr.length;
return arr.slice(0, -n % l).reduce((a,b) => {
a.push( b );
return a;
}, arr).splice(n % l> 0 ? l + (-n % l) : -n % l);
};
You can check out the performance breakdown here.
I am coming late but I have a brick to add to these good answers. I was asked to code such a function and I first did:
Array.prototype.rotate = function(n)
{
for (var i = 0; i < n; i++)
{
this.push(this.shift());
}
return this;
}
But it appeared to be less efficient than following when n
is big:
Array.prototype.rotate = function(n)
{
var l = this.length;// Caching array length before map loop.
return this.map(function(num, index) {
return this[(index + n) % l]
});
}
var arr = ['a','b','c','d']
arr.slice(1,arr.length).concat(arr.slice(0,1)
var arr = ['a','b','c','d']
arr = arr.concat(arr.splice(0,1))
function rotate(arr, k) {
for (var i = 0; i < k+1; i++) {
arr.push(arr.shift());
}
return arr;
}
//k work as an index array
console.log(rotate([1, 2, 7, 4, 5, 6, 7], 3)); //[5,6,7,1,2,7,4]
console.log(rotate([-1, -100, 3, 99], 2)); //[99,-1,-100,3]
I am sharing my solution which I am using for rotating on carousel.
It might break when array size is smaller than displayCount
, but you could add extra condition to stop rotating when it's small, or concatenating the main array *displayCount times too.
function rotate(arr, moveCount, displayCount) {
const size = arr.length;
// making sure startIndex is between `-size` and `size`
let startIndex = moveCount % size;
if (startIndex < 0) startIndex += size;
return [...arr, ...arr].slice(startIndex, startIndex + displayCount);
}
// move 3 to the right and display 4 items
// rotate([1,2,3,4,5], 3, 4) -> [4,5,1,2]
// move 3 to the left and display 4 items
// rotate([1,2,3,4,5], -3, 4) -> [3,4,5,1]
// move 11 to the right and display 4
// rotate([1,2,3,4,5], 3, 4) -> [2,3,4,5]
This function works in both way and works with any number (even with number greater than array length):
function arrayRotate(arr, count) {
count -= arr.length * Math.floor(count / arr.length);
arr.push.apply(arr, arr.splice(0, count));
return arr;
}
usage:
for(let i = -6 ; i <= 6 ; i++) {
console.log(arrayRotate(["