简体   繁体   English

如何使用多个日期时间列对javascript数组进行排序

[英]How to sort javascript array with multiple datetime columns

Given the following array: 给出以下数组:

var effectiveDates= [
    {
        actualDate: "2017-08-29",
        effectiveDate: "2017-01-01",
        time: "13:22"
    },
    {
        actualDate: "2017-08-29",
        effectiveDate: "2017-01-01",
        time: "11:33"
    },
    {
        actualDate: "2017-08-29",
        effectiveDate: "2017-01-01",
        time: "10:57"
    },
    {
        actualDate: "2016-06-17",
        effectiveDate: "2016-01-01",
        time: "10:26"
    },
    {
        actualDate: "2016-06-17",
        effectiveDate: "2016-01-01",
        time: "10:03"
    },
    {
        actualDate: "2015-12-03",
        effectiveDate: "2015-01-01",
        time: "16:54"
    },
    {
        actualDate: "2014-07-07",
        effectiveDate: "2014-05-01",
        time: "10:47"
    },
    {
        actualDate: "2014-07-07",
        effectiveDate: "2014-05-01",
        time: "10:41"
    },
    {
        actualDate: "2014-07-07",
        effectiveDate: "2014-01-01",
        time: "10:36"
    },
    {
        actualDate: "2014-07-07",
        effectiveDate: "2014-01-01",
        time: "10:36"
    }
]

I am trying to sort the data based on actualDate or effectiveDate descending (or ascending depending on the order) and then by the time (also ascending or descending based on the required order). 我试图根据actualDateeffectiveDate降序(或根据顺序升序)然后按时间(也根据所需的顺序升序或降序)对数据进行排序。 The issue I am having is that the dates order correct, but the time property does not order correctly. 我遇到的问题是日期顺序正确,但time属性没有正确排序。 I am using moment.js for the date and time parsing. 我使用moment.js进行日期和时间分析。

This is what I have attempted so far: 这是我到目前为止所尝试的:

var desc = true; //false;
effectiveDates.sort(function (a, b) {
            if (desc) {
                if (moment(a.actualDate) === moment(b.actualDate)) {
                    return (moment(b.time) - moment(a.time));
                } else if (moment(a.actualDate) < moment(b.actualDate)) {
                    return 1;
                } else if (moment(a.actualDate) > moment(b.actualDate)) {
                    return -1;
                }
            }
            else {
                if (moment(a.actualDate) === moment(b.actualDate)) {
                    return (moment(b.time) - moment(a.time));
                } else if (moment(a.actualDate) > moment(b.actualDate)) {
                    return 1;
                } else if (moment(a.actualDate) < moment(b.actualDate)) {
                    return -1;
                }
            }
        });

For some reason, when ordering the data by effectiveDate ascending or descending, the time is ordered correctly. 出于某种原因,在按effectiveDate升序或降序对数据进行排序time会正确排序time But when ordering the data by actualDate , also ascending or descending, the time data is incorrect. 但是当按actualDate排序数据时,也会按升序或降序排序, time数据不正确。

Any help would be greatly appreciated. 任何帮助将不胜感激。

Instead of 代替

return (moment(b.time) - moment(a.time));

Use: 采用:

moment(a.time, "HH:mm") - moment(b.time, "HH:mm")

You need to tell moment.js that the input strings are "time" strings. 你需要告诉moment.js输入字符串是“时间”字符串。

Three issues: 三个问题:

  1. Using === to compare two moment s won't work; 使用===比较两个moment s将不起作用; they'll never be equal. 他们永远不会平等。 Moment provides a .isSame function to do this. Moment提供了一个.isSame函数来执行此操作。
  2. To parse the times, you need to provide a format string, in this case "HH:mm" . 要解析时间,您需要提供格式字符串,在本例中为"HH:mm"
  3. The subtraction of the two times needs to reverse between ascending and descending. 减去两次需要在升序和降序之间反转。 Just flip the order. 只需翻转订单。

See a working version below, with comments indicating the changes: 请参阅下面的工作版本,其中包含指示更改的注释:

function sorted(desc) {
    return effectiveDates.sort(function (a, b) {
        if (desc) {
            // Use .isSame to compare two moments:
            if (moment(a.actualDate).isSame(moment(b.actualDate))) {
                // Provide a format to moment so it knows how to parse the times:
                return moment(b.time, "HH:mm") - moment(a.time, "HH:mm");
            } else if (moment(a.actualDate) < moment(b.actualDate)) {
                return 1;
            } else if (moment(a.actualDate) > moment(b.actualDate)) {
                return -1;
            }
        }
        else {
            if (moment(a.actualDate).isSame(moment(b.actualDate))) {
                // Reverse the order of the subtraction when sorting ascending:
                return moment(a.time, "HH:mm") - moment(b.time, "HH:mm");
            } else if (moment(a.actualDate) > moment(b.actualDate)) {
                return 1;
            } else if (moment(a.actualDate) < moment(b.actualDate)) {
                return -1;
            }
        }
    });
}

Output of these calls, 输出这些电话,

console.log("DESCENDING:");
console.log(sorted(true));

console.log("ASCENDING:");
console.log(sorted(false));

is: 是:

DESCENDING:
[ { actualDate: '2017-08-29',
    effectiveDate: '2017-01-01',
    time: '13:22' },
  { actualDate: '2017-08-29',
    effectiveDate: '2017-01-01',
    time: '11:33' },
  { actualDate: '2017-08-29',
    effectiveDate: '2017-01-01',
    time: '10:57' },
  { actualDate: '2016-06-17',
    effectiveDate: '2016-01-01',
    time: '10:26' },
  { actualDate: '2016-06-17',
    effectiveDate: '2016-01-01',
    time: '10:03' },
  { actualDate: '2015-12-03',
    effectiveDate: '2015-01-01',
    time: '16:54' },
  { actualDate: '2014-07-07',
    effectiveDate: '2014-05-01',
    time: '10:47' },
  { actualDate: '2014-07-07',
    effectiveDate: '2014-05-01',
    time: '10:41' },
  { actualDate: '2014-07-07',
    effectiveDate: '2014-01-01',
    time: '10:36' },
  { actualDate: '2014-07-07',
    effectiveDate: '2014-01-01',
    time: '10:36' } ]
ASCENDING:
[ { actualDate: '2014-07-07',
    effectiveDate: '2014-01-01',
    time: '10:36' },
  { actualDate: '2014-07-07',
    effectiveDate: '2014-01-01',
    time: '10:36' },
  { actualDate: '2014-07-07',
    effectiveDate: '2014-05-01',
    time: '10:41' },
  { actualDate: '2014-07-07',
    effectiveDate: '2014-05-01',
    time: '10:47' },
  { actualDate: '2015-12-03',
    effectiveDate: '2015-01-01',
    time: '16:54' },
  { actualDate: '2016-06-17',
    effectiveDate: '2016-01-01',
    time: '10:03' },
  { actualDate: '2016-06-17',
    effectiveDate: '2016-01-01',
    time: '10:26' },
  { actualDate: '2017-08-29',
    effectiveDate: '2017-01-01',
    time: '10:57' },
  { actualDate: '2017-08-29',
    effectiveDate: '2017-01-01',
    time: '11:33' },
  { actualDate: '2017-08-29',
    effectiveDate: '2017-01-01',
    time: '13:22' } ]

UPDATE UPDATE

A simpler comparator function: 更简单的比较器功能:

function sorted(desc) {
    return effectiveDates.sort(function (a, b) {
        // Combine the date and time and parse them together.
        var ret = moment(a.actualDate + " " + a.time) - moment(b.actualDate + " " + b.time);

        // Flip the sign if we're sorting descending.
        if (desc) {
            ret *= -1;
        }

        return ret;
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM