Sunday 12 January 2020

Sort by Multiple Criteria

In Linq ordering a collection by multiple criteria is done by invoking OrderBy with the first criteria and then chaining calls to ThenBy with each additional criteria. In order for the additional criterias to work on the collection ordered by the first criteria, we need a collection that keeps information about which items are equals based on the applied criteria and hence must be taken into account in additional criterias. This is why OrderBy and ThenBy do not return just an IEnumerable, but an IOrderedEnumerable.

In JavaScript we don't have any kind of thenBy method to apply to a sorted array, we just have the Array.prototype.sort method that sorts the array in place, so in order to sort by multiple criteria, we'll have to pass those criteria to the sort method. How? Well, pretty simple, we'll combine these criteria into a single function that we'll pass to the sort method. Let's see the code:

// Factory Function to combine multiple sort criteria
// receives functions representing sorting criteria
// returns a function that applies these criteria 
function sortByMultipleCriteriaFactory(...sortFuncs){
    return (it1, it2) => {
        for (sort of sortFuncs){
            let res = sort(it1, it2);
            if (res !== 0){
                //for this criteria items are not equal (in sorting terms) so no more criteria to apply
    return res;
            }
        }
        return res;
    };
}

So for each pair of values if the current criteria tells us that the items have the same order, we move to the next criteria in the loop, else, we just quit the loop as the other criteria are not relevant for this pair. I've put up a full example in this gist

No comments:

Post a Comment