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;
});
Portanto, o código acima classifica o array por gsize - do menor para o maior. Funciona bem. Mas se o tamanho do tamanho for o mesmo, gostaria que classificasse por brilho.
Obrigado.
javascript
arrays
Marca
fonte
fonte
Respostas:
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; } });
fonte
grouperArray.sort(function (a, b) { return a.gsize - b.gsize || a.glow - b.glow; });
versão mais curta
fonte
sort an array with a key's value first
e entãosort the result with another key's value
grouperArray.sort((a, b) => a.gsize - b.gsize || a.glow - b.glow);
Versão ainda mais curta usando sintaxe de seta!
fonte
grouperArray.sort((a,b)=>a.gsize-b.gsize||a.glow-b.glow);
Sei que isso foi perguntado há algum tempo, mas pensei em acrescentar minha solução.
Esta função gera métodos de classificação dinamicamente. simplesmente forneça cada nome de propriedade filha classificável, prefixado com +/- para indicar a ordem crescente ou decrescente. Super reutilizável e não precisa saber nada sobre a estrutura de dados que você montou. Poderia ser feito à prova de idiotas - mas não parece necessário.
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;} } } }
exemplo de uso:
items.sort (getSortMethod ('- preço', '+ prioridade', '+ nome'));
isso iria classificar
items
com menorprice
primeiro, com os laços que vão para o item com maiorpriority
. outros laços são quebrados pelo itemname
onde itens é uma 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 } ... ];
demonstração ao vivo: http://gregtaff.com/misc/multi_field_sort/
EDIT: Corrigido problema com o Chrome.
fonte
error TS2554: Expected 0 arguments, but got ..
) use a sintaxe aqui: stackoverflow.com/a/4116634/5287221Espero que a operadora ternária
((aSize < bSize) ? -1 : (aSize > bSize) ? 1 : 0;)
tenha confundido você. Você deve verificar o link para entender melhor.Até então, aqui está seu código explodido em 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; } });
fonte
Aqui está uma implementação para aqueles que desejam algo mais genérico que funcione com qualquer 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; }); }
Basicamente, você pode especificar qualquer número de nome de propriedade / direção de classificação:
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
fonte
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 ); });
fonte
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); });
fonte
Aqui está uma implementação que usa recursão para classificar por qualquer número de campos de classificação de 1 a infinito. Você passa para ele um array de resultados, que é um array de objetos de resultado a serem classificados, e um array de classificações, que é um array de objetos de classificação que definem a classificação. Cada objeto de classificação deve ter uma chave de "seleção" para o nome da chave que ele classifica e uma chave de "ordem", que é uma string indicando "crescente" ou "decrescente".
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)
fonte
Uma maneira dinâmica de fazer isso com VÁRIAS 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; } });
Usar:
// 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} ]);
fonte
Isso é o que eu uso
function sort(a, b) { var _a = "".concat(a.size, a.glow); var _b = "".concat(b.size, b.glow); return _a < _b; }
concat os dois itens como uma string e eles serão classificados por um valor de string. Se você quiser, pode envolver _a e _b com parseInt para compará-los como números, se você souber que serão numéricos.
fonte
Aqui está a solução para o caso, quando você tem uma chave de classificação de prioridade, que pode não existir em alguns itens específicos, então você tem que classificar por chaves de fallback.
Um exemplo de dados de entrada ( id2 é a chave de classificação de prioridade):
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}, ];
E a saída deve 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 } ]
A função comparadora 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 No caso de .id de .id2 poder ser zeros, considere o uso
typeof
.fonte
grouperArray.sort( function(a,b){return a.gsize == b.gsize ? a.glow - b.glow : a.gsize - b.gsize} );
fonte
grouperArray.sort(function (a, b) { var aSize = a.gsize; var bSize = b.gsize; if (aSize !== aSize) return aSize - bSize; return a.glow - b.glow; });
não testei, mas acho que deve funcionar.
fonte
No meu caso, classifico a lista de notificações pelo parâmetro 'importante' e por 'data'
passo 1: eu filtro as notificações por 'importantes' e não importantes
let importantNotifications = notifications.filter( (notification) => notification.isImportant); let unImportantNotifications = notifications.filter( (notification) => !notification.isImportant);
passo 2: eu os classifico por data
sortByDate = (notifications) => { return notifications.sort((notificationOne, notificationTwo) => { return notificationOne.date - notificationTwo.date; }); };
passo 3: mesclá-los
fonte