74

I'm wondering what is the fastest way in JavaScript to move an element from the beginning of an Array to the end. For example if we have

[8,1,2,3,4,5,6,7]

And we want: [1,2,3,4,5,6,7,8]

I want to move the first element to the end. I was thinking about switching element 0 with element 1, after that switching element 1 with element 2 and so on until the 8 is at the and (basically how bubblesort works). I was wondering if there is a faster way to bring the first element to the end.

I will be using small Arrays (around 10 elements), and I want to avoid shift() since it's pretty slow.

This is what I have now on chrome it's 45% faster than normal shift+push: http://jsperf.com/shift-myfunc

The arrays will have objects in them for a game.

4
  • 5
    It's a shame how OP is looking for the fastest way and not just a and people are giving general answers without explaining why they're faster/slower than alternatives. FGITW I guess. OP, what is your specific use case? What browsers are you targeting? How big is the array (are they always ~8 elements? Are they 10K elements?), if you want real benchmarking you need to be a lot more specific. Commented Dec 4, 2013 at 21:04
  • 1
    Thanks for editing to clarify - next round: are they arrays sparse like [1,2,,,5,8] or are they always full (like your example), do they always contain integers only? What browsers/engines are you targeting and how many iterations of these sort of shifts do you need to do per second at most? Commented Dec 4, 2013 at 21:09
  • 2
    @BenjaminGruenbaum It would have helped if the OP would have stated what they tried up front and maybe there would not have been general answers. Effort in question = effort in answer. Simple tests with JSPerf would on been nice. :) Commented Dec 4, 2013 at 21:11
  • 1
    @epascarello True - the fastest way to do something is very dependent here- on the target JS engine, on the array size, on what it contains and so on - I'm also still waiting to be convinced OP really needs it to be that fast and at what expense (if he is rotating a lot for example it might be good to keep a copy of the array concatenated to itself and slice it, work with a typed array or use other useful tricks). I know you and j08691 are definitely good guys around here from knowing a bunch of your other answer but answering one just seemed kind of pointless given the ambiguity. Commented Dec 4, 2013 at 21:15

9 Answers 9

133

Use the shift() and push() functions:

var ary = [8,1,2,3,4,5,6,7];
ary.push(ary.shift());  // results in [1, 2, 3, 4, 5, 6, 7, 8] 

Example:

var ary = [8,1,2,3,4,5,6,7];

console.log("Before: " + ary);

ary.push(ary.shift());  // results in [1, 2, 3, 4, 5, 6, 7, 8] 

console.log("After: " + ary);

2
  • 13
    For any future bypassers, how this works is using the Shift function. It removes the first item in an array and then returns it. So in other words, this code removes the first item in the array and then adds it again - making it go to the bottom of the array.
    – Alex
    Commented Jul 30, 2014 at 20:44
  • 5
    very well done... I was looking for the opposite but came up on this answer so after some quick research here is the opposite way of doing the above... ary.unshift(ary.pop());
    – Digggid
    Commented Jul 11, 2019 at 1:14
26

Use shift and push

var a = ["a","b","c"];
var b = a.shift();
a.push(b);

or

var b = a.shift();
a[a.length] = b;

Edit Based on updated question

What is going to be the fastest? Really depends on content of the array and what browser/version!

Now what are the ways to remove the first index?

  • shift()
  • splice()
  • slice()

Now what are the ways to add to the last index?

  • push()
  • array[array.length]
  • concat() -- not even going to try

Other ways

  • for loop - make new array [going to be horrible on large arrays]

JSPerf:

http://jsperf.com/test-swapping-of-first-to-last


What is really the fastest?

What is the fastest really depends on what you are doing with the array. If you are just using the first index, it will be fastest just to make your code read an index and not shift the values. If you are using all the indexes, than just loop and through and when you get to the end start back at zero. Basic counters.

5
  • 1
    I wanted to avoid the use of shift since it's pretty slow.
    – Bosiwow
    Commented Dec 4, 2013 at 21:06
  • 7
    Than say that in your question! Commented Dec 4, 2013 at 21:06
  • 2
    @user2815780 - Perhaps you should post what you've already tried in your question, including stats to show what's fast and slow?
    – j08691
    Commented Dec 4, 2013 at 21:07
  • 1
    I updated my answer with ways to do it and a JSPerf. I am sure my loop answer can be improved, I just threw it together as a break from my real work. Commented Dec 4, 2013 at 21:59
  • 1
    note that splice() returns an array so the test called "splice-push" (my personal preference) is not 100% correct. Should be: var b = arr.splice(0, 1); arr.push(b[0]);
    – BoDeX
    Commented Dec 18, 2018 at 8:35
18

And here is a sweet ES6 version

let arr = [1,2,3,4,5,6]

const [first, ...rest] = arr;
arr = [...rest,first]
1
  • 2
    That really is sweet
    – mtyson
    Commented Jan 15, 2020 at 23:21
9

Use splice to get the first element

var first = array.splice(0,1);

Then push to make if the last.

Since the return value of the splice method is an array, you have to say

array.push(first[0]);

Working example here: JSFIDDLE

7

Just in case you want to put any element to the end:

var ary = [8,1,2,3,4,5,6,7];
ary.push(ary.splice(position, 1)[0]);

for position just wrap this in a forEach.

1
  • 4
    ary.push(ary.slice(position, 1)); is wrong and would result in [8,1,2,3,4,5,6,7,Array[1] if position was 0, or [8,1,2,3,4,5,6,7,Array[0] if position was 1. I assume you wanted splice rather than slice. Cause slice doesn't remove items, and it uses the arg list start, end rather than start, deleteCount. Either way, both slice/splice return an Array, so you have to push the first item of the arr, rather than the arr itself. I fixed the code: ary.push(ary.splice(0, 1)[0]); Commented Oct 2, 2016 at 21:04
3
var a = [1,2,3,4,5,6,7,8];
var b= a[7];
var c = a.slice(1, 8);
c.push(b);

Edit: It's probably better to just shift, like epascarello did in his answer.

3

With ES20...

const newArr = [
   ...arr.slice(1),
   arr[0]
];
2

one more flavour

var arr = [0, 1, 2];
arr = arr.concat(arr.shift())

concat can add not just a element but another array at the end or beginning

0

Updating the arrays moving elements from one extreme to the other:

const array = ['First', 'Second', 'Third', 'Fourth'];

const next = [...array]
next.push(next.shift())
console.log(next); // [ 'Second', 'Third', 'Fourth', 'First' ]

const prev = [...array]
prev.unshift(prev.pop())
console.log(prev); // [ 'Fourth', 'First', 'Second', 'Third' ]

Not the answer you're looking for? Browse other questions tagged or ask your own question.