我试图通过一个属性对一组对象进行排序。当我使用比较函数对数组进行排序时,数组正在正确排序。但排序后数组的顺序会发生变化。我该怎么做才能防止它?
我已经想到了一个解决方案,我可以将数据分开:0个元素组成一个数组并对其余元素进行排序并连接两个元素。只是想知道是否有一种简单的方法吗?
注意:hex属性是我无法在比较函数中使用的对象。 hex可以有任何值或字符串。
var arr = [
{hex: "100x213123", data: 0},
{hex: "20x213223", data: 0},
{hex: "30x313123", data: 200},
{hex: "40x413123", data: 0},
{hex: "50x213123", data: 0},
{hex: "60x213123", data: 0},
{hex: "70x213123", data: 100},
{hex: "80x213123", data: 0},
{hex: "90x213123", data: 100},
{hex: "100x213123",data: 100},
{hex: "110x213123", data: 0},
{hex: "120x213123", data: 0}
].sort(function (item1,item2){
return item1.data - item2.data;
});
console.log(JSON.stringify(arr));
结果
[{"hex":"100x213123","data":0},
{"hex":"120x213123","data":0},
{"hex":"110x213123","data":0},
{"hex":"40x413123","data":0},
{"hex":"50x213123","data":0},
{"hex":"60x213123","data":0},
{"hex":"20x213223","data":0},
{"hex":"80x213123","data":0},
{"hex":"90x213123","data":100},
{"hex":"100x213123","data":100},
{"hex":"70x213123","data":100},
{"hex":"30x313123","data":200}]
预期
[{hex: "100x213123", data: 0},
{hex: "20x213223", data: 0},
{hex: "40x413123", data: 0},
{hex: "50x213123", data: 0},
{hex: "60x213123", data: 0},
{hex: "80x213123", data: 0},
{hex: "110x213123", data: 0},
{hex: "120x213123", data: 0},
{hex: "70x213123", data: 100},
{hex: "90x213123", data: 100},
{hex: "100x213123",data: 100},
{hex: "30x313123", data: 200}]
任何想法?
答案 0 :(得分:3)
如果data
相同并且对hex
值进行排序,则需要进行辅助排序:
var arr = [
{hex: "10x213123", data: 0},
{hex: "20x213223", data: 0},
{hex: "30x313123", data: 200},
{hex: "40x413123", data: 0},
{hex: "50x213123", data: 0},
{hex: "60x213123", data: 0},
{hex: "70x213123", data: 100},
{hex: "80x213123", data: 0},
{hex: "90x213123", data: 100},
{hex: "100x213123",data: 100},
{hex: "110x213123", data: 0},
{hex: "120x213123", data: 0}
].sort(function(item1, item2) {
if (item1.data !== item2.data)
return item1.data - item2.data;
else
return item1.hex.split("x")[0] - item2.hex.split("x")[0]
});
console.log(JSON.stringify(arr));

所以最好的方法是添加索引,然后将其排序为第二个键。
var arr = [
{hex: "10x213123", data: 0},
{hex: "20x213223", data: 0},
{hex: "30x313123", data: 200},
{hex: "40x413123", data: 0},
{hex: "50x213123", data: 0},
{hex: "60x213123", data: 0},
{hex: "70x213123", data: 100},
{hex: "80x213123", data: 0},
{hex: "90x213123", data: 100},
{hex: "100x213123",data: 100},
{hex: "110x213123", data: 0},
{hex: "120x213123", data: 0}
].map(function (v, i) {
v.index = i;
return v;
}).sort(function(item1, item2) {
if (item1.data !== item2.data)
return item1.data - item2.data;
else
return item1.index - item2.index
}).map(function (v) {
delete v.index;
return v;
});
console.log(JSON.stringify(arr));

然后移除index
。
答案 1 :(得分:1)
出现这种情况是因为Javascript的Array.sort不能保证是stable。这个Stack Overflow question探讨了哪些浏览器将Javascript的Array.sort实现为一个稳定的实现,并指出了如何将不稳定排序转换为稳定排序的快速解决方案。
通常,如果您想避免添加“旧索引”字段(或无法添加),您将需要拥有要排序的数组的副本 - 这使您可以先按分类器的比较器值进行排序,如果比较函数确定两个元素相等,则按旧索引排序。
例如,你可能会考虑这样的事情:
function stable_sort(original_array) {
var shallow_copy_array = original_array.slice();
original_array.sort(function(left_element, right_element) {
var comparison_result = left_element.data - right_element.data;
if (comparison_result === 0) {
return shallow_copy_array.indexOf(left_element) - shallow_copy_array.indexOf(right_element);
} else {
return comparison_result;
}
});
}
答案 2 :(得分:0)
.sort(function (item1,item2){
if (item1.data > item2.data) {
return 1;
} else if (item1.data < item2.data)
{
return -1;
} else if (item1.hex > item2.hex) {
return 1;
} else if (item1.hex < item2.hex) {
return -1;
} else {
return 0;
}
});