JavaScript排序函数 两个字段(条件)



我正在尝试按以下顺序对对象数组进行排序:

  1. 按订单优先
  2. 如果 GROUP> 0,则匹配组优先于 ORDER

例:

var obj = [
{order:1, title:"Receipts", group:0},
{order:2, title:"Apples", group:1},
{order:7, title:"Costs", group:0},
{order:4, title:"Surplus", group:0},
{order:5, title:"Bananas", group:1},
{order:6, title:"Celery", group:2},
{order:8, title:"Documents", group:0},
{order:3, title:"Potatoes", group:2}
];

var newObj = obj.sort(function(a,b) {
return (a.order - b.order || b.group - a.group);
});

console.log(newObj);

//OUTPUT SHOULD LOOK LIKE THE FOLLOWING
/*
var newObj = [
{order:1, title:"Receipts", group:0},
{order:2, title:"Apples", group:1},
{order:5, title:"Bananas", group:1},        
{order:3, title:"Potatoes", group:2}
{order:6, title:"Celery", group:2},        
{order:4, title:"Surplus", group:0},
{order:7, title:"Costs", group:0},        
{order:8, title:"Documents", group:0},        
];
//ORDER OF LOGIC
1. Function sorts by order. Sees that the first entry has GROUP = 0, continues.
2. Function sees second entry has GROUP = 1. Function finds all objects with GROUP = 1
3. After all GROUP=1 objects have been found, function continues by ORDER (next ORDER:3 is at the bottom). Function sees GROUP = 2.
4. Function finds all objects with GROUP=2.
5. After all GROUP=2 objects have been found, function continues by ORDER. The remaining objects have GROUP=0 so no changes made.
*/

我试图通过使用地图以简单的方式做到这一点......但我不知道该怎么做。我是否应该只遍历对象,当我找到记录时,将其拉出并重新循环回数组以查找类似的对象?

Array#sort

基于反复比较数组中的两个元素。如果两个元素都有非零组,这很容易:首先比较组,然后(如果它们具有相同的组(比较顺序。同样,如果两个元素都在第 0 组中,只需比较顺序即可。

棘手的地方是,如果一个元素有一个 0 组,另一个元素有一个非零组。在这种情况下,你不能直接比较它们:要确定结果数组中哪个元素应该排在第一位,你必须查看非零组中所有元素中的最低顺序。此信息不能直接获得。

我们可以通过预先传递数组并将每个非零组的最低顺序存储在关联数组中(minOf在下面的代码中(来实现它。

比较函数首先检查两个元素是否具有非零组(或两个元素都具有 0 组(。在任何一种情况下,我们都可以进行正常的双字段比较(首先group,然后order(。

否则,我们需要将组 0 中元素的order字段与非零组的minOf值进行比较。

... || -1... || 1回退在两个元素具有相同顺序但一个元素具有组 0 而另一个元素没有的情况下提供一致的顺序。

function sortGrouped(arr) {
let minOf = [];
for (const x of arr) {
if (x.group !== 0 && (minOf[x.group] === undefined || x.order < minOf[x.group])) {
minOf[x.group] = x.order;
}
}
return arr.sort((a, b) => {
if ((a.group === 0) === (b.group === 0)) {
return a.group - b.group || a.order - b.order;
}
return (
a.group === 0
? a.order - minOf[b.group] || -1
: minOf[a.group] - b.order || 1
);
});
}
const obj = [
{order:1, title:"Receipts", group:0},
{order:2, title:"Apples", group:1},
{order:7, title:"Costs", group:0},
{order:4, title:"Surplus", group:0},
{order:5, title:"Bananas", group:1},
{order:6, title:"Celery", group:2},
{order:8, title:"Documents", group:0},
{order:3, title:"Potatoes", group:2}
];

const newObj = sortGrouped(obj);

console.log(newObj);

最新更新