具有降序日期和升序时间的JavaScript排序函数

时间:2017-11-26 07:44:04

标签: javascript sorting

根据这些数据,我的排序函数将按升序日期,升序时间和按名字的字母顺序排序:

[
  ['Kurt Asdf', '25 Nov 2017 4:30 PM'],
  ['Vincent Qwerty', '25 Nov 2017 4:30 PM'],
  ['Zed Jones', '24 Nov 2017 2:00 PM'],
  ['Jack Mo', '25 Nov 2017 5:00 PM'],
  ['John Phil', '25 Nov 2017 4:00 PM'],
  ['Bob Phil', '25 Nov 2017 4:00 PM']
]

以下是我当前排序函数的输出(下面的代码):

[
  ['Zed Jones', '24 Nov 2017 2:00 PM'],
  ['Bob Phil', '25 Nov 2017 4:00 PM'],
  ['John Phil', '25 Nov 2017 4:00 PM'],
  ['Kurt Asdf', '25 Nov 2017 4:30 PM'],
  ['Vincent Qwerty', '25 Nov 2017 4:30 PM'],
  ['Jack Mo', '25 Nov 2017 5:00 PM']
]

这是我想要的输出:

[
  ['Bob Phil', '25 Nov 2017 4:00 PM'],
  ['John Phil', '25 Nov 2017 4:00 PM'],
  ['Kurt Asdf', '25 Nov 2017 4:30 PM'],
  ['Vincent Qwerty', '25 Nov 2017 4:30 PM'],
  ['Jack Mo', '25 Nov 2017 5:00 PM'],
  ['Zed Jones', '24 Nov 2017 2:00 PM']
]

请注意,在上面的输出中,日期是按降序排列的,但是时间是按升序排列的,并且每个时间段内的字母顺序都是保持不变的。

以下是我的尝试:

function sortTable(data) {
  return data.sort((elem1, elem2) => {
    var dateA         = new Date(elem1[1])
      , dateB         = new Date(elem2[1])
      , nameA         = elem1[0]
      , nameB         = elem2[0]
      , datecomp      = dateB-dateA;

    if (nameA === undefined || nameB === undefined)
      namecomp = 0;
    else
      namecomp = nameA[0] > nameB[0] || -(nameA[0] < nameB[0]);

    return datecomp > 0 ? datecomp : datecomp + namecomp;
  });
}

1 个答案:

答案 0 :(得分:1)

我保持可读性的建议是将日期分为日期和时间,以便将它们分开进行比较:

// number of milliseconds in a day = 24 * 3600 * 1000 = 24 * 36e5
millis = date.getTime()
time = millis % (24 * 36e5)
day = millis - time

JavaScript日期精度以毫秒为单位,因此date.getTime()给出自1970-01-01以来经过的毫秒数。这就是我要做的事情:

var dates = [
  new Date(2017, 0, 1, 0, 0, 1),
  new Date(2017, 0, 2, 0, 0, 2),
  new Date(2017, 0, 3, 0, 0, 1),
  new Date(2017, 0, 2, 0, 0, 1),
  new Date(2017, 0, 3, 0, 0, 2),
  new Date(2017, 0, 1, 0, 0, 2)
];

dates.sort(function (date1, date2) {
  var millisInADay = 24 * 36e5;
  var millis1 = date1.getTime();
  var millis2 = date2.getTime();
  var time1 = millis1 % millisInADay;
  var time2 = millis2 % millisInADay;
  var day1 = millis1 - time1;
  var day2 = millis2 - time2;
  if (day1 < day2) return 1;
  if (day1 > day2) return -1;
  if (time1 > time2) return 1;
  if (time1 < time2) return -1;
  return 0;
});

dates.forEach(function (date) {
  console.log(date.toLocaleString());
});

以下是使用您自己的数据表的结果:

var table = [
  ['Kurt Asdf', '25 Nov 2017 4:30 PM'],
  ['Vincent Qwerty', '25 Nov 2017 4:30 PM'],
  ['Zed Jones', '24 Nov 2017 2:00 PM'],
  ['Jack Mo', '25 Nov 2017 5:00 PM'],
  ['John Phil', '25 Nov 2017 4:00 PM'],
  ['Bob Phil', '25 Nov 2017 4:00 PM']
];

table.sort(function (x1, x2) {
  var millisInADay = 24 * 36e5;
  var name1 = x1[0];
  var name2 = x2[0];
  var date1 = new Date(x1[1]);
  var date2 = new Date(x2[1]);
  var millis1 = date1.getTime();
  var millis2 = date2.getTime();
  var time1 = millis1 % millisInADay;
  var time2 = millis2 % millisInADay;
  var day1 = millis1 - time1;
  var day2 = millis2 - time2;
  if (day1 < day2) return 1;
  if (day1 > day2) return -1;
  if (time1 > time2) return 1;
  if (time1 < time2) return -1;
  if (name1 > name2) return 1;
  if (name1 < name2) return -1;
  return 0;
});

table.forEach(function (x) {
  var date = new Date(x[1]);
  console.log(date.toLocaleString(), "|", x[0]);
});