User case: data should be sorted by custom values, which don’t make logical order. Look at the following data:

const list = [
  { category: 'tv', price: 1400 },
  { category: 'smartphones', price: 590 },
  { category: 'notebooks', price: 1500 },
  { category: 'smartphones', price: 350 }
]

We would like to sort the objects in the following order: smartphones, notebooks, anything else and have no control over the order data is fetched. First, we need to create an object with that is going to hold priorities:

let sortingOrder = {
    'smartphones': 1,
    'notebooks': 2
}

We are going to use standard array sorting method from the prototype, but need to write a comparison function. Let’s make it take the property name and sorting order as parameters, so it can be reused.

function compare(key, order = 'asc') {
    return function (a, b) {
        if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) 
	    return 0;
		
	const first = (a[key].toLowerCase() in sortingOrder) ? sortingOrder[a[key]] : Number.MAX_SAFE_INTEGER;
	const second = (b[key].toLowerCase() in sortingOrder) ? sortingOrder[b[key]] : Number.MAX_SAFE_INTEGER;
		
	let result = 0;
	if (first < second) 
	    result = -1;
	else if (first > second) 
	    result = 1;
	return (order === 'desc') ? ~result : result
    };
}

We use the comparator function to determine the order from keys. Number.MAX_SAFE_INTEGER is used to be sure note specified elements are always last in undetermined order and we are free to extend sortingOrder object. Finally, (order === ‘desc’) ? ~result : result inverts the comparison result for descending order. Lastly, we sort the array as follows:

list.sort(compare('category'));
// OR
list.sort(compare('category', 'desc'));
There are currently no comments.

This site uses Akismet to reduce spam. Learn how your comment data is processed.