How can I sort an ImmutableJS List object on multiple keys?

孤人 提交于 2019-12-12 05:00:01

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!