Rotate the elements in an array in JavaScript

Solution 1:

You can use push(), pop(), shift() and unshift() methods:

function arrayRotate(arr, reverse) {
  if (reverse) arr.unshift(arr.pop());
  else arr.push(arr.shift());
  return arr;
}

usage:

arrayRotate([1, 2, 3, 4, 5]);       // [2, 3, 4, 5, 1];
arrayRotate([1, 2, 3, 4, 5], true); // [5, 1, 2, 3, 4];

If you need count argument see my other answer:
https://stackoverflow.com/a/33451102 πŸ–€πŸ§‘πŸ’šπŸ’™πŸ’œ

Solution 2:

Type-safe, generic version which mutates the array:

Array.prototype.rotate = (function() {
    // save references to array functions to make lookup faster
    var push = Array.prototype.push,
        splice = Array.prototype.splice;

    return function(count) {
        var len = this.length >>> 0, // convert to uint
            count = count >> 0; // convert to int

        // convert count to value in range [0, len)
        count = ((count % len) + len) % len;

        // use splice.call() instead of this.splice() to make function generic
        push.apply(this, splice.call(this, 0, count));
        return this;
    };
})();

In the comments, Jean raised the issue that the code doesn't support overloading of push() and splice(). I don't think this is really useful (see comments), but a quick solution (somewhat of a hack, though) would be to replace the line

push.apply(this, splice.call(this, 0, count));

with this one:

(this.push || push).apply(this, (this.splice || splice).call(this, 0, count));

Using unshift() instead of push() is nearly twice as fast in Opera 10, whereas the differences in FF were negligible; the code:

Array.prototype.rotate = (function() {
    var unshift = Array.prototype.unshift,
        splice = Array.prototype.splice;

    return function(count) {
        var len = this.length >>> 0,
            count = count >> 0;

        unshift.apply(this, splice.call(this, count % len, len));
        return this;
    };
})();

Solution 3:

I would probably do something like this:

Array.prototype.rotate = function(n) {
    n = n % this.length;
    return this.slice(n, this.length).concat(this.slice(0, n));
}

EditΒ Β Β Β Here’s a mutator version:

Array.prototype.rotate = function(n) {
    n = n % this.length;
    while (this.length && n < 0) n += this.length;
    this.push.apply(this, this.splice(0, n));
    return this;
}

Solution 4:

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(["🧑","πŸ’š","πŸ’™","πŸ’œ","πŸ–€"], i), i);
}

result:

[ "πŸ–€", "🧑", "πŸ’š", "πŸ’™", "πŸ’œ" ]    -6
[ "🧑", "πŸ’š", "πŸ’™", "πŸ’œ", "πŸ–€" ]    -5
[ "πŸ’š", "πŸ’™", "πŸ’œ", "πŸ–€", "🧑" ]    -4
[ "πŸ’™", "πŸ’œ", "πŸ–€", "🧑", "πŸ’š" ]    -3
[ "πŸ’œ", "πŸ–€", "🧑", "πŸ’š", "πŸ’™" ]    -2
[ "πŸ–€", "🧑", "πŸ’š", "πŸ’™", "πŸ’œ" ]    -1
[ "🧑", "πŸ’š", "πŸ’™", "πŸ’œ", "πŸ–€" ]    0
[ "πŸ’š", "πŸ’™", "πŸ’œ", "πŸ–€", "🧑" ]    1
[ "πŸ’™", "πŸ’œ", "πŸ–€", "🧑", "πŸ’š" ]    2
[ "πŸ’œ", "πŸ–€", "🧑", "πŸ’š", "πŸ’™" ]    3
[ "πŸ–€", "🧑", "πŸ’š", "πŸ’™", "πŸ’œ" ]    4
[ "🧑", "πŸ’š", "πŸ’™", "πŸ’œ", "πŸ–€" ]    5
[ "πŸ’š", "πŸ’™", "πŸ’œ", "πŸ–€", "🧑" ]    6