[英]Sorting an array in order to move an element from one place to another, while keeping `order` field the same
I'm trying to sort an array based on its order
field, and I'm having a bit of trouble.我正在尝试根据其
order
字段对数组进行排序,但遇到了一些麻烦。
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.注意每个结果 object 的
order
字段如何不比前一个大 1。 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.到数组的第二位(
array[1]
),同时保留所有order
值。
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:我试图以这样的方式对这个新数组进行排序,output 应该是:
[
{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.我也尝试过使用
splice
将元素从其原始位置拉出并将其放置在新的预期 position 中,但我遇到了order
字段的排序问题。
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?您可以在数组中提取订单并
shift
以获取下一个订单? 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.这将有效地保持
name
属性的顺序,并将基于order
order
。
Do not attempt to modify the array while sorting.排序时不要尝试修改数组。 Instead:
反而:
Array#splice
to move the item to a new positionArray#splice
将项目移动到新的 positionorder
parameter of the sub-section of the array where the item was moved:order
参数: 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:或者这是一种替代方法,首先拍摄当前
order
s 的快照,然后在交换后将其恢复到数组的受影响子部分:
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.您可以使用对象的属性之一对对象数组进行排序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.