DEV Community

Cover image for How to shift array position in vanilla JavaScript

How to shift array position in vanilla JavaScript

Knut Melvær on December 19, 2018

I was helping a user over at sanity.io yesterday doing some content migration, where they wanted to take the last element of an array and put it in...
Collapse
 
lexlohr profile image
Alex Lohr •

Why not use a really simple solution with plain ES5?

function lastToFirst(array) {
  const result = array.slice(0);
  result.unshift(result.pop());
  return result;
}
Collapse
 
somedood profile image
Basti Ortiz •

I mean it would be ES5 if const was var. 😂

Anyway, I like how concise it is. Three lines of code sure does look more satisfying than whatever I did, despite their similarities.

Collapse
 
link2twenty profile image
Andrew Bone •

I agree this is readable.

If you handed this to a new developer and asked them what it did they might be lost for a little while.

const lastToFirst = _ => [_.pop(), ..._];
Collapse
 
lexlohr profile image
Alex Lohr •

Also, that would change the original array, which is not the intended functionality.

Thread Thread
 
link2twenty profile image
Andrew Bone • • Edited

Good point, you'd have to do something like

const lastToFirst = _ => {const $ = _.slice(); return [$.pop(), ...$]};

which is even more convoluted.

Thread Thread
 
lexlohr profile image
Alex Lohr •

How about const lastToFirst = _ => ($ => [$.pop(), ...$])(_.slice()) as even more convoluted example?

Collapse
 
somedood profile image
Basti Ortiz • • Edited

I think this will do just fine.

function shiftArray(arr) {
  // Get the last element in the array
  const lastElement = arr[arr.length - 1];

  // Prepend the `lastElement` to the start of the array
  arr.unshift(lastElement);

  // Remove the duplicate element at the end of the array
  arr.pop();

  // Hooray! We party! 🎉
  return arr;
}

// Plop in `theList`
shiftArray(theList);
Collapse
 
thomasjunkos profile image
Thomas Junkツ • • Edited

I would go for

const lastToFirst = (arr) => [arr.pop(), ...arr]

or

ltf= function(arr){ return [arr.pop()].concat(arr) }
Collapse
 
thejoezack profile image
Joe Zack •

ES6 FTW!

Collapse
 
bgadrian profile image
Adrian B.G. •

Probably that array is not going to be accessed using the index, it looks like an unordered collection.

If this is true you need a linked list not an array, making the move operation 2N more efficient and resulting in a simpler code.

Collapse
 
thejoezack profile image
Joe Zack •

Great point! Array Data Structures aren't very efficient at arbitrarily inserting or plucking (even though JS provides convenient shift/deshift methods.)

With this small of a dataset it doesn't matter, but it's a great point. :)

Collapse
 
kennethtruyers profile image
Kenneth Truyers •

I very much like the plain ES5 solution by @lexlohr . Here's another, more generic version that lets you rotate an array by a variable number of positions:

const rotateArray = (array, count) => {
  const arr = [...array];

  count = (count || 0) % arr.length;
  if (count < 0)  count += arr.length;

  var removed = arr.splice(0, count);
  arr.push.apply(arr, removed);

  return arr;
}
Collapse
 
wolfhoundjesse profile image
Jesse M. Holmes •

Everyone is talking about your code, and I'm stuck appreciating this beautiful gem:

Not ideal (unless you're Arya).

Collapse
 
kmelve profile image
Knut Melvær •

Thank you for noticing!