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). The issue I am having is that the dates order correct, but the time
property does not order correctly. I am using moment.js for the date and time parsing.
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. But when ordering the data by actualDate
, also ascending or descending, the time
data is incorrect.
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.
Three issues:
===
to compare two moment
s won't work; they'll never be equal. Moment provides a .isSame
function to do this. "HH:mm"
. 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
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;
});
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.