按给定顺序排序的Javascript数组

时间:2017-01-04 01:21:04

标签: javascript arrays sorting

我试图通过一个属性对一组对象进行排序。当我使用比较函数对数组进行排序时,数组正在正确排序。但排序后数组的顺序会发生变化。我该怎么做才能防止它?

我已经想到了一个解决方案,我可以将数据分开: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}]

任何想法?

3 个答案:

答案 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;
 }

});