Reordering arrays

JavascriptArraysSorting

Javascript Problem Overview


Say, I have an array that looks like this:

var playlist = [
	{artist:"Herbie Hancock", title:"Thrust"},
	{artist:"Lalo Schifrin", title:"Shifting Gears"},
	{artist:"Faze-O", title:"Riding High"}
];

How can I move an element to another position?

I want to move for example, {artist:"Lalo Schifrin", title:"Shifting Gears"} to the end.

I tried using splice, like this:

var tmp = playlist.splice(2,1);
playlist.splice(2,0,tmp);

But it doesn't work.

Javascript Solutions


Solution 1 - Javascript

The syntax of Array.splice is:

yourArray.splice(index, howmany, element1, /*.....,*/ elementX);

Where:

  • index is the position in the array you want to start removing elements from
  • howmany is how many elements you want to remove from index
  • element1, ..., elementX are elements you want inserted from position index.

This means that splice() can be used to remove elements, add elements, or replace elements in an array, depending on the arguments you pass.

Note that it returns an array of the removed elements.

Something nice and generic would be:

Array.prototype.move = function (from, to) {
  this.splice(to, 0, this.splice(from, 1)[0]);
};

Then just use:

var ar = [1,2,3,4,5];
ar.move(0,3);
alert(ar) // 2,3,4,1,5

Diagram:

Algorithm diagram

Solution 2 - Javascript

If you know the indexes you could easily swap the elements, with a simple function like this:

function swapElement(array, indexA, indexB) {
  var tmp = array[indexA];
  array[indexA] = array[indexB];
  array[indexB] = tmp;
}

swapElement(playlist, 1, 2);
// [{"artist":"Herbie Hancock","title":"Thrust"},//  {"artist":"Faze-O","title":"Riding High"},//  {"artist":"Lalo Schifrin","title":"Shifting Gears"}]

Array indexes are just properties of the array object, so you can swap its values.

Solution 3 - Javascript

Here is an immutable version for those who are interested:

function immutableMove(arr, from, to) {
  return arr.reduce((prev, current, idx, self) => {
    if (from === to) {
      prev.push(current);
    }
    if (idx === from) {
      return prev;
    }
    if (from < to) {
      prev.push(current);
    }
    if (idx === to) {
      prev.push(self[from]);
    }
    if (from > to) {
      prev.push(current);
    }
    return prev;
  }, []);
}

Solution 4 - Javascript

With ES6 you can do something like this:

const swapPositions = (array, a ,b) => {
  [array[a], array[b]] = [array[b], array[a]]
}

let array = [1,2,3,4,5];
swapPositions(array,0,1);

/// => [2, 1, 3, 4, 5]

Solution 5 - Javascript

You could always use the sort method, if you don't know where the record is at present:

playlist.sort(function (a, b) {
    return a.artist == "Lalo Schifrin" 
               ? 1    // Move it down the list
               : 0;   // Keep it the same
});

Solution 6 - Javascript

Change 2 to 1 as the first parameter in the splice call when removing the element:

var tmp = playlist.splice(1, 1);
playlist.splice(2, 0, tmp[0]);

Solution 7 - Javascript

Immutable version, no side effects (doesn’t mutate original array):

const testArr = [1, 2, 3, 4, 5];

function move(from, to, arr) {
    const newArr = [...arr];

    const item = newArr.splice(from, 1)[0];
    newArr.splice(to, 0, item);

    return newArr;
}

console.log(move(3, 1, testArr));

// [1, 4, 2, 3, 5]

codepen: https://codepen.io/mliq/pen/KKNyJZr

Solution 8 - Javascript

EDIT: Please check out Andy's answer as his answer came first and this is solely an extension of his

I know this is an old question, but I think it's worth it to include Array.prototype.sort().

Here's an example from MDN along with the link

var numbers = [4, 2, 5, 1, 3];
numbers.sort(function(a, b) {
  return a - b;
});
console.log(numbers);

// [1, 2, 3, 4, 5]

Luckily it doesn't only work with numbers:

> # arr.sort([compareFunction]) > ### compareFunction > Specifies a function that defines the sort order. If omitted, the array is sorted according to each character's Unicode code point value, according to the string conversion of each element.

I noticed that you're ordering them by first name:

let playlist = [
    {artist:"Herbie Hancock", title:"Thrust"},
    {artist:"Lalo Schifrin", title:"Shifting Gears"},
    {artist:"Faze-O", title:"Riding High"}
];

// sort by name
playlist.sort((a, b) => {
  if(a.artist < b.artist) { return -1; }
  if(a.artist > b.artist) { return  1; }

  // else names must be equal
  return 0;
});

note that if you wanted to order them by last name you would have to either have a key for both first_name & last_name or do some regex magic, which I can't do XD

Hope that helps :)

Solution 9 - Javascript

Try this:

playlist = playlist.concat(playlist.splice(1, 1));

Solution 10 - Javascript

If you only ever want to move one item from an arbitrary position to the end of the array, this should work:

function toEnd(list, position) {
    list.push(list.splice(position, 1));
    return list;
}

If you want to move multiple items from some arbitrary position to the end, you can do:

function toEnd(list, from, count) {
    list.push.apply(list, list.splice(from, count));
    return list;
}

If you want to move multiple items from some arbitrary position to some arbitrary position, try:

function move(list, from, count, to) {
    var args = [from > to ? to : to - count, 0];
    args.push.apply(args, list.splice(from, count));
    list.splice.apply(list, args);
    
    return list;
}

Solution 11 - Javascript

As a simple mutable solution you can call splice twice in a row:

playlist.splice(playlist.length - 1, 1, ...playlist.splice(INDEX_TO_MOVE, 1))

On the other hand, a simple inmutable solution could use slice since this method returns a copy of a section from the original array without changing it:

const copy = [...playlist.slice(0, INDEX_TO_MOVE - 1), ...playlist.slice(INDEX_TO_MOVE), ...playlist.slice(INDEX_TO_MOVE - 1, INDEX_TO_MOVE)]

Solution 12 - Javascript

Reorder its work This Way

 var tmpOrder = playlist[oldIndex];
    playlist.splice(oldIndex, 1);
    playlist.splice(newIndex, 0, tmpOrder);

I hope this will work

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWurlitzerView Question on Stackoverflow
Solution 1 - JavascriptMattView Answer on Stackoverflow
Solution 2 - JavascriptChristian C. SalvadóView Answer on Stackoverflow
Solution 3 - JavascriptchmanieView Answer on Stackoverflow
Solution 4 - JavascriptarthurDentView Answer on Stackoverflow
Solution 5 - JavascriptAndy EView Answer on Stackoverflow
Solution 6 - JavascriptTrevorView Answer on Stackoverflow
Solution 7 - JavascriptMichael LiquoriView Answer on Stackoverflow
Solution 8 - JavascriptJaacko TorusView Answer on Stackoverflow
Solution 9 - JavascriptJamieJagView Answer on Stackoverflow
Solution 10 - JavascriptOkonomiyaki3000View Answer on Stackoverflow
Solution 11 - JavascriptDavidView Answer on Stackoverflow
Solution 12 - JavascriptPeriView Answer on Stackoverflow