简体   繁体   中英

Reorder elements in array of objects

I have an array of objects:

const array = [
  {
    id: "5a2524432b68c725c06ac987",
    customOrder: 1,
    name: "One",
  },
  {
    id: "5a2524432b68sgs25c06ac987",
    customOrder: 2,
    name: "Two",
  },
  {
    id: "5a252wfew32b68c725c06ac987",
    customOrder: 3,
    name: "Three",
  },
  {
    id: "5a25gffe32b68c725c06ac987",
    customOrder: 4,
    name: "Four",
  },
  {
    id: "5a2524432b68c725c06acfee7",
    customOrder: 5,
    name: "Five",
  },
  {
    id: "5a2524432b68c725c06ac556",
    customOrder: 6,
    name: "Six",
  },
]

When I update the customOrder of one of the objects and update the other objects based on customOrder So if I change index 2 to have a custom order of 4, I need to edit the customOrder of the other elements so it the result would be:

const array = [
  {
    id: "5a2524432b68c725c06ac987",
    customOrder: 1,
    name: "One",
  },
  {
    id: "5a2524432b68sgs25c06ac987",
    customOrder: 2,
    name: "Two",
  },
  {
    id: "5a25gffe32b68c725c06ac987",
    customOrder: 3,
    name: "Four",
  },
  {
    id: "5a252wfew32b68c725c06ac987",
    customOrder: 4,
    name: "Three",
  }
  {
    id: "5a2524432b68c725c06acfee7",
    customOrder: 5,
    name: "Five",
  },
  {
    id: "5a2524432b68c725c06ac556",
    customOrder: 6,
    name: "Six",
  },
]

I'm thinking of using array.slice() or even using lodash _.putAt() but I am trying to think of a simple way of achieving the best result

You can do it in four steps:

  1. Use Array.findIndex() to locate the entry having the same value as the value you want to update at the given index.

  2. Then change the value of this entry to the value of the item at the given index.

  3. Then update the item at the given index with the new value.

  4. Finally, swap the items. If there was no item with the new value, sort the array to make sure the item gets put at the right position.

This version mutates the array:

 const array = [{id:"5a2524432b68c725c06ac987",customOrder:1,name:"One",},{id:"5a2524432b68sgs25c06ac987",customOrder:2,name:"Two",},{id:"5a252wfew32b68c725c06ac987",customOrder:3,name:"Three",},{id:"5a25gffe32b68c725c06ac987",customOrder:4,name:"Four",},{id:"5a2524432b68c725c06acfee7",customOrder:5,name:"Five",},{id:"5a2524432b68c725c06ac556",customOrder:6,name:"Six",},] const swap = (arr, x, y) => [arr[x], arr[y]] = [arr[y], arr[x]]; function setOrder(arr, idx, value) { const idx2 = arr.findIndex(x => x.customOrder === value); if (idx2 >= 0) arr[idx2].customOrder = arr[idx].customOrder; arr[idx].customOrder = value; if (idx2 >= 0) swap(arr, idx, idx2); else arr.sort((a, b) => a.customOrder - b.customOrder); return arr; } setOrder(array, 2, 4); console.log(array); setOrder(array, 2, 10); console.log(array);

This version does not mutate the array:

 const array = [{id:"5a2524432b68c725c06ac987",customOrder:1,name:"One",},{id:"5a2524432b68sgs25c06ac987",customOrder:2,name:"Two",},{id:"5a252wfew32b68c725c06ac987",customOrder:3,name:"Three",},{id:"5a25gffe32b68c725c06ac987",customOrder:4,name:"Four",},{id:"5a2524432b68c725c06acfee7",customOrder:5,name:"Five",},{id:"5a2524432b68c725c06ac556",customOrder:6,name:"Six",},] const swap = (arr, x, y) => [arr[x], arr[y]] = [arr[y], arr[x]]; function setOrder(arr, idx, value) { const out = [...arr]; const idx2 = out.findIndex(x => x.customOrder === value); if (idx2 >= 0) out[idx2] = { ...out[idx2], customOrder: out[idx].customOrder }; out[idx] = { ...out[idx], customOrder: value }; if (idx2 >= 0) swap(out, idx, idx2); else out.sort((a, b) => a.customOrder - b.customOrder); return out; } console.log(setOrder(array, 2, 4)); console.log(setOrder(array, 2, 10));

You can use splice to remove an item at an index and move it to the new index specified. Then update the customOrder using forEach

(You can take a copy of the array using spread syntax and use map if you don't want to mutate the original array)

 const array = [{id:"5a2524432b68c725c06ac987",customOrder:1,name:"One",},{id:"5a2524432b68sgs25c06ac987",customOrder:2,name:"Two",},{id:"5a252wfew32b68c725c06ac987",customOrder:3,name:"Three",},{id:"5a25gffe32b68c725c06ac987",customOrder:4,name:"Four",},{id:"5a2524432b68c725c06acfee7",customOrder:5,name:"Five",},{id:"5a2524432b68c725c06ac556",customOrder:6,name:"Six",},] function updateOrder(input, index, newIndex) { let copy = [...input]; const removed = copy.splice(index, 1); copy.splice(newIndex, 0, removed[0]); return copy.map((a, i) => ({ ...a, customOrder: i+1 })) } console.log(updateOrder(array, 2, 3))

With mutation:

 const array = [{id:"5a2524432b68c725c06ac987",customOrder:1,name:"One",},{id:"5a2524432b68sgs25c06ac987",customOrder:2,name:"Two",},{id:"5a252wfew32b68c725c06ac987",customOrder:3,name:"Three",},{id:"5a25gffe32b68c725c06ac987",customOrder:4,name:"Four",},{id:"5a2524432b68c725c06acfee7",customOrder:5,name:"Five",},{id:"5a2524432b68c725c06ac556",customOrder:6,name:"Six",},] function updateOrderMutation(input, index, newIndex) { const removed = input.splice(index, 1); input.splice(newIndex, 0, removed[0]); input.forEach((a, i) => a.customOrder = i + 1) return input; } console.log(updateOrderMutation(array, 2, 3))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM