Recently, I've been working on integrating Recurly.js - a client-side credit-card processing library - into our application. When Recurly.js validates the credit-card form, it returns a list of invalid fields. Unfortunately, the order of the returned fields doesn't necessarily reflect the order in which they appear in the user interface (UI). When formatting the subsequent error message, I wanted the order of the error items to match the arbitrary order in the UI. To do this, I used Lodash's intersection() method.
Lodash's intersection() method wasn't necessarily designed for sorting values. But, when you have a set of simple values, it turns out to be a really convenient way of sorting one set of values against another set of values. When intersection() runs, it compares the values across a set of collections; but, when it returns the values, it pulls them out of the first array in that set. What this means is that we can use the first array to drive the order of the resultant collection and the second array to drive the intersection itself.
// Require the core node modules. var _ = require( "lodash" ); // This is the subset of values that we have been provided with (perhaps by a system // that we do not control, like a 3rd-party validation library); but, we don't want to // process the values in the order in which they were provided - we want to process them // according to an arbitrary order (below). var providedValues = [ "e", "f", "c", "7", "a", "3" ]; // This is the full set of "known values" in the correct order in which they should // be processed. They are in an arbitrary order, perhaps driven by the User Interface. var orderedValues = "01234567890abcdef".split( "" ); // By using intersection(), we allow the first operand to drive the order of the resultant // set of values. But, we use the second operand - the provided values - to drive the // actual intersection calculation. This way, the provided values get pulled out of the // "ordered" values in the correct order. console.log( "Provided Values:", providedValues ); console.log( "Ordered Values:", _.intersection( orderedValues, providedValues ) );
Here, we have a provided collection of values that we want to sort according to a known set of values. We'll let the known set drive the order and then let the provided values drive the intersection. And, when we run the above code through Node.js, we get the following terminal output:
Provided Values: [ 'e', 'f', 'c', '7', 'a', '3' ]
Ordered Values: [ '3', '7', 'a', 'c', 'e', 'f' ]
As you can see, the provided values get re-ordered according to the arbitrary sort of the known set of values.
Obviously, this isn't an approach that can be used with any set of values; the values have to be simple and the desired order has to be small and known ahead of time. But, when these conditions are met, I find this to be a really trivial way of applying an arbitrary sort to set of values.