为什么这会丢失排序顺序?

时间:2016-01-21 01:32:50

标签: javascript sorting debugging

出于我们的前端应用程序的目的,我需要摄取一个对象数组(比如大约20个),然后将数组转换为Key / Value对象。

data = [
    {name: 'first', uid: 789, start: '2016-01-20 08:00:00'},
    {name: 'second', uid: 492, start: '2016-01-20 15:00:00'},
    {name: 'third', uid: 324, start: '2016-01-20 10:00:00'},
    {name: 'fourth', uid: 923, start: '2016-01-20 14:30:00'},
    // ...
];

然后我对此start

进行排序
data.sort(function (a, b) {
    var aStart = new Date(a.start),
        bStart = new Date(b.start);

    if (aStart < bStart) return -1;
    if (aStart > bStart) return 1;
    return 0;
});

然后,为了快速访问基于UID的数据,我遍历这个已排序的数组并将其转换为K / V对象:

var stored = {};
for (var i = 0; i < data.length; i++) {
    stored[data[i].uid] = data[i];
}

这使我可以执行类似stored[uid]的操作,而不必在每次需要给定对象的索引时循环遍历data

问题

在循环并创建stored对象时,我似乎正在丢失排序顺序。

排序后:

2016-01-20 08:00:00 // 789
2016-01-20 10:00:00 // 324
2016-01-20 14:30:00 // 923
2016-01-20 15:00:00 // 492

转换为Object

Object.keys(sorted).map(function (id, index) {
    console.log(sorted[id].start)
});

收率:

2016-01-20 08:00:00 // 789
2016-01-20 14:30:00 // 923
2016-01-20 15:00:00 // 492
2016-01-20 10:00:00 // 324

正如您所看到的,10AM事件(324)现在位于列表的末尾,我不确定为什么会发生这种情况。

1 个答案:

答案 0 :(得分:1)

正如thefourtheye所说,虽然有些引擎确实保留了对象中的插入顺序,但并不是必需的。有两种方法可以保持属性的顺序:

  • 保留一系列已排序的键;迭代该数组以按顺序访问对象属性。

var data = [
  {name: 'first', uid: 789, start: '2016-01-20 08:00:00'},
  {name: 'second', uid: 492, start: '2016-01-20 15:00:00'},
  {name: 'third', uid: 324, start: '2016-01-20 10:00:00'},
  {name: 'fourth', uid: 923, start: '2016-01-20 14:30:00'}
];

var stored = {};
for (var i = 0; i < data.length; i++) {
  stored[data[i].uid] = data[i];
}

var keys = Object.keys(stored);
keys.sort(function(a, b) {
  var aStart = new Date(stored[a].start),
  var bStart = new Date(stored[b].start);

  if (aStart < bStart) return -1;
  if (aStart > bStart) return 1;
  return 0;
});

keys.forEach(function(key) {
  console.log(stored[key].start);
});
<!-- results pane console output; see http://meta.stackexchange.com/a/242491 -->
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>

  • 使用ES6 Map,保证保持广告订单。

var data = [
  {name: 'first', uid: 789, start: '2016-01-20 08:00:00'},
  {name: 'second', uid: 492, start: '2016-01-20 15:00:00'},
  {name: 'third', uid: 324, start: '2016-01-20 10:00:00'},
  {name: 'fourth', uid: 923, start: '2016-01-20 14:30:00'}
];

data.sort(function(a, b) {
  var aStart = new Date(a.start),
    bStart = new Date(b.start);

  if (aStart < bStart) return -1;
  if (aStart > bStart) return 1;
  return 0;
});

var stored = new Map();
for (var i = 0; i < data.length; i++) {
  stored.set(data[i].uid, data[i]);
}

stored.forEach(function(value) {
  console.log(value.start);
});
<!-- results pane console output; see http://meta.stackexchange.com/a/242491 -->
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>