¿Es el siguiente patrón una buena manera de hacer ordenaciones múltiples, por ejemplo, algo similar a:
ORDER BY id ASC, name DESC, date ASC let people = [ {Name: 'Alex', Age: 20}, {Name: 'George', Age: 20}, {Name: 'Tommy', Age: 11}, ]; function cmpPeople(p1, p2) { // Age ASC if (p1.Age != p2.Age) { return p1.Age - p2.Age; // numeric fields can use subtraction } // Name DESC else if (p1.Name != p2.Name) { return (p1.Name > p2.Name) ? -1 : 1; } // Placeholder at end else return 0; } people.sort(cmpPeople); console.log(people);Si no, ¿cuál podría ser una forma más limpia de encadenar varios tipos de forma similar a cómo se comunica con SQL?
Puede tomar una matriz de claves deseadas y su orden e iterar esta matriz hasta que un valor sea diferente de cero.
const ASC = (a, b) => a > b || -(a < b), DESC = (a, b) => ASC(b, a), sortBy = columns => (a, b) => { let r = 0; columns.some(([key, fn]) => r = fn(a[key], b[key])); return r; } people = [{ Name: 'George', Age: 20 }, { Name: 'Alex', Age: 20 }, { Name: 'Tommy', Age: 11 }], order = [ ['Age', ASC], ['Name', ASC] ]; people.sort(sortBy(order)); console.log(people); .as-console-wrapper { max-height: 100% !important; top: 0; }Lo que tienes funciona, pero quizás aquí hay un método más sucinto. Usando la función flecha, podemos devolver un resultado sin return . La primera comparación devuelve la diferencia de edad a menos que sea cero, en cuyo caso devuelve la segunda comparación que usa localeCompare
let people = [{Name: 'Alex', Age: 20}, {Name: 'George', Age: 20}, {Name: 'Tommy', Age: 11}]; const cmpPeople = (p1, p2) => p1.Age - p2.Age || p2.Name.localeCompare(p1.Name) people.sort(cmpPeople); console.log(people);La dirección es correcta. Lo else es redundante. Además, su comparador es muy específico (contiene lógica comercial), no puede reutilizarlo. Lo tomé como un ejercicio y escribí un generador de comparación genérico.
let people = [ { Name: "Alex", Age: 20 }, { Name: "George", Age: 20 }, { Name: "George", Age: 11 }, { Name: "George", Age: 10 }, { Name: "Tommy", Age: 11 }, ]; function getComparator(fields) { return function (p1, p2) { for (let i = 0; i < fields.length; i++) { const v1 = p1[fields[i].field]; const v2 = p2[fields[i].field]; // It should work for numbers & strings in same way if (v1 > v2) return fields[i].order === "asc" ? 1 : -1; if (v1 < v2) return fields[i].order === "asc" ? -1 : 1; } return 0; }; } const comparator = getComparator([ { field: "Age", order: "asc" }, { field: "Name", order: "desc" }, ]); people.sort(comparator); console.log(people);