[英]Sort an array of objects by multiple properties
I have an array of objects like this:我有一个像这样的对象数组:
var a = [
{ id: 1, score: 1, isCut: false, dnf: false },
{ id: 2, score: 2, isCut: false, dnf: false },
{ id: 3, score: 3, isCut: false, dnf: false },
{ id: 4, score: 4, isCut: false, dnf: false },
{ id: 5, score: 5, isCut: true, dnf: true },
{ id: 6, score: 6, isCut: true, dnf: false },
{ id: 7, score: 7, isCut: true, dnf: false },
{ id: 8, score: 8, isCut: true, dnf: false },
{ id: 9, score: 9, isCut: true, dnf: false },
{ id: 10, score: 0, isCut: false, dnf: false },
{ id: 11, score: -1, isCut: false, dnf: false },
{ id: 12, score: -2, isCut: false, dnf: true },
{ id: 13, score: -3, isCut: false, dnf: false },
{ id: 14, score: -4, isCut: false, dnf: false },
{ id: 15, score: -5, isCut: false, dnf: false },
{ id: 16, score: 10, isCut: true, dnf: false }
];
I need to group and sort the array by the following criteria:我需要按以下标准对数组进行分组和排序:
dnf
is true, object goes to bottom;dnf
为真,则对象移至底部; all dnf
-objects should be sorted by scorednf
-objects 应按分数排序isCut
is true, object goes to bottom, but above dnf
s;isCut
为真,则对象进入底部,但在dnf
之上; all isCut
-objects should be sorted by scoreisCut
-objects 应按分数排序score
, and if the scores are equal, by id
score
排序,如果分数相等, id
(Updated) Here's the answer of question you mentioned in comment. (更新)这是您在评论中提到的问题的答案。
a.sort(function(a, b) {
if (a.dnf != b.dnf) {
return a.dnf ? 1 : -1;
}
if (!(a.dnf && b.dnf) && a.isCut != b.isCut) {
return a.isCut ? 1 : -1;
}
if (a.score != b.score) {
return b.score - a.score; // descending
}
return b.id - a.id; // descending
});
Result:结果:
[
{"id":4,"score":4,"isCut":false,"dnf":false}, // the rest: order by score, id
{"id":3,"score":3,"isCut":false,"dnf":false}, //
{"id":2,"score":2,"isCut":false,"dnf":false}, //
{"id":1,"score":1,"isCut":false,"dnf":false}, //
{"id":10,"score":0,"isCut":false,"dnf":false}, //
{"id":11,"score":-1,"isCut":false,"dnf":false}, //
{"id":13,"score":-3,"isCut":false,"dnf":false}, //
{"id":14,"score":-4,"isCut":false,"dnf":false}, //
{"id":15,"score":-5,"isCut":false,"dnf":false}, //
{"id":16,"score":10,"isCut":true,"dnf":false}, // isCut: order by score, id
{"id":9,"score":9,"isCut":true,"dnf":false}, //
{"id":8,"score":8,"isCut":true,"dnf":false}, //
{"id":7,"score":7,"isCut":true,"dnf":false}, //
{"id":6,"score":6,"isCut":true,"dnf":false}, //
{"id":5,"score":5,"isCut":true,"dnf":true}, // dnf: order by score, id
{"id":12,"score":-2,"isCut":false,"dnf":true} //
]
Use comparator function from Array使用 Array 中的比较器函数
you can check answers here : Sort array of objects by string property value in JavaScript您可以在此处查看答案: 在 JavaScript 中按字符串属性值对对象数组进行排序
This is a different approach, which uses an array for the sort order, which is irregular, if using dnf
and isCut
property without looking at both.这是一种不同的方法,它使用一个数组作为排序顺序,如果使用
dnf
和isCut
属性而不查看两者,则这是不规则的。 If we take a both values to a truth table, then the sort order does not reflect the wanted order.如果我们将两个值都放入真值表,则排序顺序不会反映所需的顺序。
2*dnf+isCut dnf isCut value order -------- -------- -------- -------- 0 0 0 0 0 1 1 1 1 1 3 2 1 0 2 3
To correct the sort order, I suggest to use an array for getting the right order.为了更正排序顺序,我建议使用数组来获得正确的顺序。
var data = [{ id: 1, score: 1, isCut: false, dnf: false }, { id: 2, score: 2, isCut: false, dnf: false }, { id: 3, score: 3, isCut: false, dnf: false }, { id: 4, score: 4, isCut: false, dnf: false }, { id: 5, score: 5, isCut: true, dnf: true }, { id: 6, score: 6, isCut: true, dnf: false }, { id: 7, score: 7, isCut: true, dnf: false }, { id: 8, score: 8, isCut: true, dnf: false }, { id: 9, score: 9, isCut: true, dnf: false }, { id: 10, score: 0, isCut: false, dnf: false }, { id: 11, score: -1, isCut: false, dnf: false }, { id: 12, score: -2, isCut: false, dnf: true }, { id: 13, score: -3, isCut: false, dnf: false }, { id: 14, score: -4, isCut: false, dnf: false }, { id: 15, score: -5, isCut: false, dnf: false }, { id: 16, score: 10, isCut: true, dnf: false }]; data.sort(function (a, b) { function order(dnf, isCut) { return [0, 1, 3, 2][dnf * 2 + isCut]; } return order(a.dnf, a.isCut) - order(b.dnf, b.isCut) || b.score - a.score; }); console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can do it in one line with Alasql library: 您可以使用Alasql库在一行中完成此操作 :
var res = alasql('SELECT * FROM ? ORDER BY dnf, isCut, score, id',[a]);
Try the example with your data at jsFiddle . 在jsFiddle上使用数据尝试该示例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.