20

I have this array:

var arr1 = ['a1', 'a2', 'a3', 'a4', 'a5'];

I need to shift it to right by say 2 locations, like

arr1 = ['a4', 'a5', 'a1', 'a2', 'a3']; 

This works for left shift:

arr1 = arr1.concat(arr1.splice(0,2)); // shift left by 2

I get :

arr1 = ['a3', 'a4', 'a5', 'a1', 'a2']; 

But I don't know how to do shift right...

Ja͢ck
  • 166,373
  • 34
  • 252
  • 304
mike44
  • 792
  • 5
  • 14
  • 36

3 Answers3

22

You can use .pop() to get the last item and .unshift() to put it at the front:

function shiftArrayToRight(arr, places) {
    for (var i = 0; i < places; i++) {
        arr.unshift(arr.pop());
    }
}
gilly3
  • 83,908
  • 25
  • 139
  • 172
21

Shift to right to N positions == shift to left to array.length - N positions.

So to shift right on 2 positions for you array - just shift it left on 3 positions.

There is no reason to implement another function as soon as you already have one. Plus solutions with shift/unshift/pop in a loop barely will be as efficient as splice + concat

zerkms
  • 240,587
  • 65
  • 429
  • 525
11

Using .concat() you're building a new Array, and replacing the old one. The problem with that is that if you have other references to the Array, they won't be updated, so they'll still hold the unshifted version.

To do a right shift, and actually mutate the existing Array, you can do this:

arr1.unshift.apply(arr1, arr1.splice(3,2));

The unshift() method is variadic, and .apply lets you pass multiple arguments stored in an Array-like collection.

So the .splice() mutates the Array by removing the last two, and returning them, and .unshift() mutates the Array by adding the ones returned by .splice() to the beginning.


The left shift would be rewritten similar to the right shift, since .push() is also variadic:

arr1.push.apply(arr1, arr1.splice(0,2));