I have a function which sorts by name currently and an array of value / key pairs.
I wonder how can I pass the key on which sort is being performed so I can call the same function every time like so:
var arr = [{name:'bob', artist:'rudy'}, {name:'johhny', artist:'drusko'}, {name:'tiff', artist:'needell'}, {name:'top', artist:'gear'}]; sort(arr, 'name'); //trying to sort by name sort(arr, 'artist'); //trying to sort by artist function sort(arr) { arr.sort(function(a, b) { var nameA=a.name.toLowerCase(), nameB=b.name.toLowerCase(); if (nameA < nameB) //sort string ascending return -1; if (nameA > nameB) return 1; return 0; //default return value (no sorting) }); }
Advertisement
Answer
[edit 2020/08/14] This was rather an old answer and not very good as well, so simplified and revised.
Create a function that returns the sorting lambda (the Array.prototype.sort
callback that does the actual sorting). That function can receive the key name, the kind of sorting (string (case sensitive or not) or numeric) and the sorting order (ascending/descending). The lambda uses the parameter values (closure) to determine how to sort.
const log = (...strs) => document.querySelector("pre").textContent += `n${strs.join("n")}`; const showSortedValues = (arr, key) => ` => ${arr.reduce((acc, val) => ([...acc, val[key]]), [])}`; // the actual sort lamda factory function const sortOnKey = (key, string, desc) => { const caseInsensitive = string && string === "CI"; return (a, b) => { a = caseInsensitive ? a[key].toLowerCase() : a[key]; b = caseInsensitive ? b[key].toLowerCase() : b[key]; if (string) { return desc ? b.localeCompare(a) : a.localeCompare(b); } return desc ? b - a : a - b; } }; // a few examples const onNameStringAscendingCaseSensitive = getTestArray().sort( sortOnKey("name", true) ); const onNameStringAscendingCaseInsensitive = getTestArray().sort( sortOnKey("name", "CI", true) ); const onValueNumericDescending = getTestArray().sort( sortOnKey("value", false, true) ); // examples log(`*key = name, string ascending case sensitive`, showSortedValues(onNameStringAscendingCaseSensitive, "name") ); log(`n*key = name, string descending case insensitive`, showSortedValues(onNameStringAscendingCaseInsensitive, "name") ); log(`n*key = value, numeric desc`, showSortedValues(onValueNumericDescending, "value") ); function getTestArray() { return [{ name: 'Bob', artist: 'Rudy', value: 23, }, { name: 'John', artist: 'Drusko', value: 123, }, { name: 'Tiff', artist: 'Needell', value: 1123, }, { name: 'Top', artist: 'Gear', value: 11123, }, { name: 'john', artist: 'Johanson', value: 12, }, ]; }
<pre></pre>