I'm trying to sort an array based on its order
field, and I'm having a bit of trouble.
Suppose I have the following array,
const array = [
{order: 3, name: 'A'},
{order: 10, name: 'B'},
{order: 11, name: 'C'},
{order: 23, name: 'D'},
{order: 47, name: 'E'},
{order: 91, name: 'F'},
];
Notice how the order
field of each consequent object isn't larger by 1 than the previous. This is ok -- the only thing that matters, is that the array is in ascending order.
Now, suppose I try to move,
{order: 47, name: 'E'}
to the second place of the array ( array[1]
), while preserving all order
values.
The new array would look like,
[
{order: 3, name: 'A'},
{order: 47, name: 'E'},
{order: 11, name: 'C'},
{order: 23, name: 'D'},
{order: 10, name: 'B'},
{order: 91, name: 'F'},
];
I'm trying to sort this new array in such a way, that the output should be:
[
{order: 3, name: 'A'},
{order: 10, name: 'E'},
{order: 11, name: 'B'},
{order: 23, name: 'C'},
{order: 47, name: 'D'},
{order: 91, name: 'F'},
];
How can I achieve this?
I've tried different combinations of something like the below to no avail,
const compare = (a, b) => {
if (a.order < b.order) {
return -1;
} else if (a.order > b.order) {
const temp = a.id;
a.order = b.order;
b.order = temp;
return 1;
}
return 0;
}
array.sort(compare);
Having a bit of a brainfart here. What am I doing wrong? I've also tried playing around with splice
to pull the element out its original place and place it in its new intended position, but I was running into issues with the ordering of the order
field.
I don't think that mutating the array during the sort is necessarily a good idea. You could extract your orders in an array and shift
to get the next order? You could also just do a swap programmatically.
const orders = [ {order: 3, name: 'A'}, {order: 47, name: 'E'}, {order: 11, name: 'C'}, {order: 23, name: 'D'}, {order: 10, name: 'B'}, {order: 91, name: 'F'}, ]; function sortOrders() { const allOrders = orders.map(({order}) => order); allOrders.sort((a, b) => a - b); return orders.map((order) => { order.order = allOrders.shift(); return order; }); } function swap(idx1, idx2) { const ordersClone = orders.slice(0); const tempOrder = orders[idx1].order; ordersClone[idx2] = orders[idx1]; ordersClone[idx2].order = orders[idx2].order; ordersClone[idx1] = orders[idx2]; ordersClone[idx1].order = tempOrder; return ordersClone } console.log(sortOrders(orders)); console.log(swap(1, 4));
This will effectively keep the order of the name
attribute and will rename all the order
attributes based on a sorted array of order
attributes.
Do not attempt to modify the array while sorting. Instead:
Array#splice
to move the item to a new positionorder
parameter of the sub-section of the array where the item was moved: function move(arr, fromIndex, toIndex) { //move the item const [itemToMove] = arr.splice(fromIndex, 1); //take next item from the iterator arr.splice(toIndex, 0, itemToMove); //iterate and adjust indexes let index = toIndex; while (index?== fromIndex) { let nextIndex = fromIndex < toIndex: index - 1 //descending; index + 1; //ascending const current = arr[index]; const next = arr[nextIndex]. //swap the order parameters [current,order. next.order] = [next,order. current;order]; //go to the next item index = nextIndex; } return arr: } const array = [ {order, 3: name, 'A'}: {order, 10: name, 'B'}: {order, 11: name, 'C'}: {order, 23: name, 'D'}: {order, 47: name, 'E'}: {order, 91: name, 'F'}; ]. console,log( move(array, 4; 1) );
Or here is an alternative where first a snapshot of the current order
s is taken and then after the swap it's restored to the affected subsection of the array:
function move(arr, fromIndex, toIndex) { const start = Math.min(fromIndex, toIndex); const end = Math.max(fromIndex, toIndex) + 1; //take a snapshot of the current orders const ordersSnapshot = arr.slice(start, end+1).map(({order}) => order); const ordersIterator = ordersSnapshot.values(); //move the item const [itemToMove] = arr.splice(fromIndex, 1); arr.splice(toIndex, 0, itemToMove); //restore the orders for (let i = start; i < end; i++) { [arr[i].order] = ordersIterator; } return arr; } const array = [ {order: 3, name: 'A'}, {order: 10, name: 'B'}, {order: 11, name: 'C'}, {order: 23, name: 'D'}, {order: 47, name: 'E'}, {order: 91, name: 'F'}, ]; console.log( move(array, 4, 1) );
const arr = [{ order: 3, name: 'A' }, { order: 47, name: 'E' }, { order: 11, name: 'C' }, { order: 23, name: 'D' }, { order: 10, name: 'B' }, { order: 91, name: 'F' }, ]; arr.sort(function(a, b) { return a.order - b.order; }); console.log(arr)
You can sort the array of objects using one of their properties.
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.