grouperArray.sort(function (a, b) {
var aSize = a.gsize;
var bSize = b.gsize;
var aLow = a.glow;
var bLow = b.glow;
console.log(aLow + " | " + bLow);
return (aSize < bSize) ? -1 : (aSize > bSize) ? 1 : 0;
});
Entonces, el código anterior ordena la matriz por gsize, de menor a mayor. Funciona bien. Pero si el tamaño de g es el mismo, me gustaría ordenarlo por brillo.
Gracias.
javascript
arrays
marca
fuente
fuente
Respuestas:
grouperArray.sort(function (a, b) { var aSize = a.gsize; var bSize = b.gsize; var aLow = a.glow; var bLow = b.glow; console.log(aLow + " | " + bLow); if(aSize == bSize) { return (aLow < bLow) ? -1 : (aLow > bLow) ? 1 : 0; } else { return (aSize < bSize) ? -1 : 1; } });
fuente
grouperArray.sort(function (a, b) { return a.gsize - b.gsize || a.glow - b.glow; });
versión más corta
fuente
sort an array with a key's value first
y luegosort the result with another key's value
grouperArray.sort((a, b) => a.gsize - b.gsize || a.glow - b.glow);
¡Versión aún más corta con sintaxis de flechas!
fuente
grouperArray.sort((a,b)=>a.gsize-b.gsize||a.glow-b.glow);
Me doy cuenta de que esto se preguntó hace algún tiempo, pero pensé en agregar mi solución.
Esta función genera métodos de clasificación de forma dinámica. simplemente proporcione el nombre de cada propiedad secundaria clasificable, precedido de +/- para indicar el orden ascendente o descendente. Súper reutilizable y no necesita saber nada sobre la estructura de datos que ha reunido. Podría hacerse a prueba de idiotas, pero no parece necesario.
function getSortMethod(){ var _args = Array.prototype.slice.call(arguments); return function(a, b){ for(var x in _args){ var ax = a[_args[x].substring(1)]; var bx = b[_args[x].substring(1)]; var cx; ax = typeof ax == "string" ? ax.toLowerCase() : ax / 1; bx = typeof bx == "string" ? bx.toLowerCase() : bx / 1; if(_args[x].substring(0,1) == "-"){cx = ax; ax = bx; bx = cx;} if(ax != bx){return ax < bx ? -1 : 1;} } } }
ejemplo de uso:
items.sort (getSortMethod ('- precio', '+ prioridad', '+ nombre'));
esto se ordenaría primero
items
con el más bajoprice
, y los vínculos con el elemento con el más altopriority
. más lazos se rompen por el artículoname
donde elementos es una matriz como:
var items = [ { name: "z - test item", price: "99.99", priority: 0, reviews: 309, rating: 2 }, { name: "z - test item", price: "1.99", priority: 0, reviews: 11, rating: 0.5 }, { name: "y - test item", price: "99.99", priority: 1, reviews: 99, rating: 1 }, { name: "y - test item", price: "0", priority: 1, reviews: 394, rating: 3.5 }, { name: "x - test item", price: "0", priority: 2, reviews: 249, rating: 0.5 } ... ];
demostración en vivo: http://gregtaff.com/misc/multi_field_sort/
EDITAR: problema solucionado con Chrome.
fuente
error TS2554: Expected 0 arguments, but got ..
) use la sintaxis aquí: stackoverflow.com/a/4116634/5287221Supongo que el operador ternario lo
((aSize < bSize) ? -1 : (aSize > bSize) ? 1 : 0;)
tiene confundido. Debería consultar el enlace para comprenderlo mejor.Hasta entonces, aquí está su código completo if / else.
grouperArray.sort(function (a, b) { if (a.gsize < b.gsize) { return -1; } else if (a.gsize > b.gsize) { return 1; } else { if (a.glow < b.glow) { return -1; } else if (a.glow > b.glow) { return 1; } return 0; } });
fuente
Aquí hay una implementación para aquellos que deseen algo más genérico que funcione con cualquier número de campos.
Array.prototype.sortBy = function (propertyName, sortDirection) { var sortArguments = arguments; this.sort(function (objA, objB) { var result = 0; for (var argIndex = 0; argIndex < sortArguments.length && result === 0; argIndex += 2) { var propertyName = sortArguments[argIndex]; result = (objA[propertyName] < objB[propertyName]) ? -1 : (objA[propertyName] > objB[propertyName]) ? 1 : 0; //Reverse if sort order is false (DESC) result *= !sortArguments[argIndex + 1] ? 1 : -1; } return result; }); }
Básicamente, puede especificar cualquier número de nombre de propiedad / dirección de clasificación:
var arr = [{ LastName: "Doe", FirstName: "John", Age: 28 }, { LastName: "Doe", FirstName: "Jane", Age: 28 }, { LastName: "Foo", FirstName: "John", Age: 30 }]; arr.sortBy("LastName", true, "FirstName", true, "Age", false); //Will return Jane Doe / John Doe / John Foo arr.sortBy("Age", false, "LastName", true, "FirstName", false); //Will return John Foo / John Doe / Jane Doe
fuente
grouperArray.sort(function (a, b) { var aSize = a.gsize; var bSize = b.gsize; var aLow = a.glow; var bLow = b.glow; console.log(aLow + " | " + bLow); return (aSize < bSize) ? -1 : (aSize > bSize) ? 1 : ( (aLow < bLow ) ? -1 : (aLow > bLow ) ? 1 : 0 ); });
fuente
grouperArray.sort(function (a, b) { var aSize = a.gsize; var bSize = b.gsize; var aLow = a.glow; var bLow = b.glow; console.log(aLow + " | " + bLow); return (aSize < bSize) ? -1 : (aSize > bSize) ? 1 : (aLow < bLow) ? -1 : (aLow > bLow) ? 1 : 0); });
fuente
Aquí hay una implementación que usa la recursividad para ordenar por cualquier número de campos de ordenación desde 1 hasta infinito. Le pasa una matriz de resultados que es una matriz de objetos de resultado para ordenar, y una matriz de ordenaciones que es una matriz de objetos de ordenación que definen la ordenación. Cada objeto de clasificación debe tener una clave de "seleccionar" para el nombre de la clave por la que se ordena y una clave de "orden", que es una cadena que indica "ascendente" o "descendente".
sortMultiCompare = (a, b, sorts) => { let select = sorts[0].select let order = sorts[0].order if (a[select] < b[select]) { return order == 'ascending' ? -1 : 1 } if (a[select] > b[select]) { return order == 'ascending' ? 1 : -1 } if(sorts.length > 1) { let remainingSorts = sorts.slice(1) return this.sortMultiCompare(a, b, remainingSorts) } return 0 } sortResults = (results, sorts) => { return results.sort((a, b) => { return this.sortMultiCompare(a, b, sorts) }) } // example inputs const results = [ { "LastName": "Doe", "FirstName": "John", "MiddleName": "Bill" }, { "LastName": "Doe", "FirstName": "Jane", "MiddleName": "Bill" }, { "LastName": "Johnson", "FirstName": "Kevin", "MiddleName": "Bill" } ] const sorts = [ { "select": "LastName", "order": "ascending" }, { "select": "FirstName", "order": "ascending" }, { "select": "MiddleName", "order": "ascending" } ] // call the function like this: let sortedResults = sortResults(results, sorts)
fuente
Una forma dinámica de hacer eso con MÚLTIPLES teclas:
Object.defineProperty(Array.prototype, 'orderBy', { value: function(sorts) { sorts.map(sort => { sort.uniques = Array.from( new Set(this.map(obj => obj[sort.key])) ); sort.uniques = sort.uniques.sort((a, b) => { if (typeof a == 'string') { return sort.inverse ? b.localeCompare(a) : a.localeCompare(b); } else if (typeof a == 'number') { return sort.inverse ? (a < b) : (a > b ? 1 : 0); } else if (typeof a == 'boolean') { let x = sort.inverse ? (a === b) ? 0 : a? -1 : 1 : (a === b) ? 0 : a? 1 : -1; return x; } return 0; }); }); const weightOfObject = (obj) => { let weight = ""; sorts.map(sort => { let zeropad = `${sort.uniques.length}`.length; weight += sort.uniques.indexOf(obj[sort.key]).toString().padStart(zeropad, '0'); }); //obj.weight = weight; // if you need to see weights return weight; } this.sort((a, b) => { return weightOfObject(a).localeCompare( weightOfObject(b) ); }); return this; } });
Utilizar:
// works with string, number and boolean let sortered = your_array.orderBy([ {key: "type", inverse: false}, {key: "title", inverse: false}, {key: "spot", inverse: false}, {key: "internal", inverse: true} ]);
fuente
Esto es lo que yo uso
function sort(a, b) { var _a = "".concat(a.size, a.glow); var _b = "".concat(b.size, b.glow); return _a < _b; }
Concat los dos elementos como una cadena y se ordenarán por un valor de cadena. Si lo desea, puede envolver _a y _b con parseInt para compararlos como números si sabe que serán numéricos.
fuente
Aquí está la solución para el caso, cuando tiene una clave de clasificación de prioridad, que podría no existir en algunos elementos en particular, por lo que debe ordenar por claves de reserva.
Un ejemplo de datos de entrada ( id2 es la clave de clasificación de prioridad):
const arr = [ {id: 1}, {id: 2, id2: 3}, {id: 4}, {id: 3}, {id: 10, id2: 2}, {id: 7}, {id: 6, id2: 1}, {id: 5}, {id: 9, id2: 2}, {id: 8}, ];
Y la salida debería ser:
[ { id: 6, id2: 1 }, { id: 9, id2: 2 }, { id: 10, id2: 2 }, { id: 2, id2: 3 }, { id: 1 }, { id: 3 }, { id: 4 }, { id: 5 }, { id: 7 }, { id: 8 } ]
La función del comparador será como:
arr.sort((a,b) => { if(a.id2 || b.id2) { if(a.id2 && b.id2) { if(a.id2 === b.id2) { return a.id - b.id; } return a.id2 - b.id2; } return a.id2 ? -1 : 1; } return a.id - b.id });
PS En caso de que el .id de .id2 pueda ser ceros, considere usar
typeof
.fuente
grouperArray.sort( function(a,b){return a.gsize == b.gsize ? a.glow - b.glow : a.gsize - b.gsize} );
fuente
grouperArray.sort(function (a, b) { var aSize = a.gsize; var bSize = b.gsize; if (aSize !== aSize) return aSize - bSize; return a.glow - b.glow; });
no probado, pero creo que debería funcionar.
fuente
En mi caso, ordeno la lista de notificaciones por parámetro 'importante' y por 'fecha'
paso 1: filtro las notificaciones por 'importante' y no importante
let importantNotifications = notifications.filter( (notification) => notification.isImportant); let unImportantNotifications = notifications.filter( (notification) => !notification.isImportant);
paso 2: los ordeno por fecha
sortByDate = (notifications) => { return notifications.sort((notificationOne, notificationTwo) => { return notificationOne.date - notificationTwo.date; }); };
paso 3: fusionarlos
fuente