问题
I have a list of work history objects that have start
and end
date fields. I need to sort by start
and then by end
. If the dates overlap between work history objects when I use back-to-back sort()
functions, the order can potentially be off. I need a way to sort an ImmutableJS List by multiple keys where the second sort key is only processed when first key values are equal. I would have assumed that ImmutableJS would have a simpler way to handle this type of sorting. Here is what I came up with, but this feels horrible to me (using momentJS for date comparison):
const sortedWorkHistory = workHistory.sort((b, a) => {
const aTo = moment(a.get('to') === null ? undefined : a.get('to'));
const bTo = moment(b.get('to') === null ? undefined : b.get('to'));
if (aTo.isBefore(bTo)) {
return -1;
}
if (bTo.isBefore(aTo)) {
return 1;
}
return 0;
})
.sort((b, a) => {
const aTo = moment(a.get('to') === null ? undefined : a.get('to'));
const bTo = moment(b.get('to') === null ? undefined : b.get('to'));
if (aTo === bTo) {
const aFrom = moment(a.get('from'));
const bFrom = moment(b.get('from'));
if (aFrom.isBefore(bFrom)) {
return -1;
}
if (bFrom.isBefore(aFrom)) {
return 1;
}
return 0;
}
});
回答1:
aTo === bTo
is never going to be equal the way you are defining it. You're comparing references to objects which are always different. You'll need to use moments .isSame
method. You can verify that by trying this:
const a = moment().startOf('day');
const b = moment().startOf('day');
console.log(a === b); // false
console.log(a.isSame(b)); // true
Here is what I'd do:
// Helper function to create moments
function parseMoment(date) {
return moment(date === null ? undefined : date);
}
const sortedWorkHistory = workHistory
.sort((a, b) => parseMoment(a.get('to')).diff(parseMoment(b.get('to'))))
.sort((a, b) => {
if(parseMoment(a.get('to')).isSame(parseMoment(b.get('to')))) {
return parseMoment(a.get('from')).diff(parseMoment(b.get('from')))
}
return 0;
});
回答2:
You could put that into a single compare function like this:
const sortedWorkHistory = workHistory.sort((b, a) => {
const aTo = moment(a.get('to'));
const bTo = moment(b.get('to'));
const aFrom = moment(a.get('from'));
const bFrom = moment(b.get('from'));
if (aTo.isBefore(bTo)) {
return -1;
} else if (bTo.isBefore(aTo)) {
return 1;
} else if (aFrom.isBefore(bFrom)) {
return -1;
} else if (bFrom.isBefore(aFrom)) {
return 1;
}
return 0;
});
Or maybe even
const sortedWorkHistory = workHistory.sort((b, a) => {
// aTo = ...
if (aTo.isSame(bTo)) {
return aFrom.diff(bFrom);
}
return aTo.diff(bTo);
});
来源:https://stackoverflow.com/questions/46936825/how-can-i-sort-an-immutablejs-list-object-on-multiple-keys