2

I have an array with objects sorted by key 'order'

[
  {order: 1, id: 1, title: elem1},
  {order: 2, id: 2, title: elem2},
  {order: 3, id: 3, title: elem3},
  {order: 4, id: 4, title: elem4},
  {order: 5, id: 5, title: elem5}
]

after change key 'order' in 'elem2' to '4', array should look like this

[
  {order: 1, id: 1, title: elem1},  
  {order: 2, id: 3, title: elem3},
  {order: 3, id: 4, title: elem4},
  {order: 4, id: 2, title: elem2},
  {order: 5, id: 5, title: elem5}
]

I wanna move an objects in the array after changing key 'order' in some object in both direction

zerocool
  • 21
  • 4
  • Array.prototype.sort – VLAZ Aug 10 '16 at 20:23
  • Possible duplicate of [Sorting an array of JavaScript objects](http://stackoverflow.com/questions/979256/sorting-an-array-of-javascript-objects) – VLAZ Aug 10 '16 at 20:25
  • @Vld - It's more an 'extract' and 'insert back' operation. Item #3 is moving as well. Not sure how this could be done with a sort. – Arnauld Aug 10 '16 at 22:03
  • @Arnauld By sorting-that's what sorting does, it arranges elements by default or specified rules. – Dave Newton Aug 10 '16 at 22:14
  • @Arnauld seriously, dude? What sorting does is that it _sorts stuff_. `objects.sort((a, b) => a.order - b.order)`. This complex and incomprehensible solution took me 5 seconds to implement. – VLAZ Aug 11 '16 at 09:29

2 Answers2

2

You can use Array.prototype.sort() function:

var elem1, elem2, elem3, elem4, elem5;
var arr = [
  {order: 1, id: 1, title: elem1},
  {order: 2, id: 2, title: elem2},
  {order: 3, id: 3, title: elem3},
  {order: 4, id: 4, title: elem4},
  {order: 5, id: 5, title: elem5}
];

arr[1].order = 4;
arr[3].order = 2;

arr.sort((a, b) => a.order > b.order);
madox2
  • 49,493
  • 17
  • 99
  • 99
1

You can use .splice() to move the item and .forEach() to update the order property.

var arr = [
  {order: 1, id: 1, title: 'elem1'},
  {order: 2, id: 2, title: 'elem2'},
  {order: 3, id: 3, title: 'elem3'},
  {order: 4, id: 4, title: 'elem4'},
  {order: 5, id: 5, title: 'elem5'}
];

function moveItem(arr, from, to) {
  arr.splice(to - 1, 0, arr.splice(from - 1, 1)[0]);
  arr.forEach(function(e, i) { e.order = i + 1; });
}

moveItem(arr, 2, 4);

// formatted output
console.log(JSON.stringify(arr).split('},').join('},\n'));
Arnauld
  • 5,847
  • 2
  • 15
  • 32
  • Why wouldn't you just supply a sort function that compares the order property value of each element? I mean, your approach seems very brittle and unnecessary, no? And there's a working example from an hour ago. – Dave Newton Aug 10 '16 at 22:15
  • @DaveNewton I may be missing something here, but I still don't get it. By just sorting (like the other answer does), item #3 will remain at the same position. This is _not_ what the OP wants. – Arnauld Aug 10 '16 at 22:22
  • In fairness to you it's not clear what the OP expects if two order values are the same. – Dave Newton Aug 11 '16 at 01:01
  • @DaveNewton My understanding is that the OP wants to move element A at position B, shifting all elements between A and B towards the beginning of the array, then update the 'order' properties to reflect the new arrangement. – Arnauld Aug 11 '16 at 01:09
  • (or shifting towards the end of the array when B is before A) – Arnauld Aug 11 '16 at 01:19
  • `function moveItem(arr, from, to) { arr[from].order = to; arr[to].order = from; arr.sort((a, b) => a.order - b.order)}` – VLAZ Aug 11 '16 at 09:32
  • @Vld Sorry to insist, but this is not doing what the OP wants. I apparently failed to explain that, but please have a closer look at the desired output. – Arnauld Aug 11 '16 at 09:54