Como classificar uma matriz de objects por vários campos?

A partir dessa pergunta original , como eu aplicaria uma sorting em vários campos?

Usando esta estrutura ligeiramente adaptada, como classificaria a cidade (ascendente) e depois o preço (descendente)?

var homes = [ {"h_id":"3", "city":"Dallas", "state":"TX", "zip":"75201", "price":"162500"}, {"h_id":"4", "city":"Bevery Hills", "state":"CA", "zip":"90210", "price":"319250"}, {"h_id":"6", "city":"Dallas", "state":"TX", "zip":"75000", "price":"556699"}, {"h_id":"5", "city":"New York", "state":"NY", "zip":"00010", "price":"962500"} ]; 

Gostei do fato do que uma resposta que forneceu uma abordagem geral. Onde pretendo usar este código, terei que ordenar datas e outras coisas. A capacidade de “preparar” o object parecia útil, se não um pouco incômoda.

Eu tentei construir essa resposta em um bom exemplo genérico, mas não estou tendo muita sorte.

Um método de sorting multidimensional, baseado nesta resposta :

Atualização : aqui está uma versão “otimizada”. Ele faz muito mais pré-processamento e cria uma function de comparação para cada opção de sorting antecipadamente. Pode precisar de mais memory (uma vez que armazena uma function para cada opção de sorting, mas deve ser um pouco melhor, pois não precisa determinar as configurações corretas durante a comparação. Porém, não fiz nenhum perfil.

 var sort_by; (function() { // utility functions var default_cmp = function(a, b) { if (a == b) return 0; return a < b ? -1 : 1; }, getCmpFunc = function(primer, reverse) { var dfc = default_cmp, // closer in scope cmp = default_cmp; if (primer) { cmp = function(a, b) { return dfc(primer(a), primer(b)); }; } if (reverse) { return function(a, b) { return -1 * cmp(a, b); }; } return cmp; }; // actual implementation sort_by = function() { var fields = [], n_fields = arguments.length, field, name, reverse, cmp; // preprocess sorting options for (var i = 0; i < n_fields; i++) { field = arguments[i]; if (typeof field === 'string') { name = field; cmp = default_cmp; } else { name = field.name; cmp = getCmpFunc(field.primer, field.reverse); } fields.push({ name: name, cmp: cmp }); } // final comparison function return function(A, B) { var a, b, name, result; for (var i = 0; i < n_fields; i++) { result = 0; field = fields[i]; name = field.name; result = field.cmp(A[name], B[name]); if (result !== 0) break; } return result; } } }()); 

Exemplo de uso:

 homes.sort(sort_by('city', {name:'price', primer: parseInt, reverse: true})); 

DEMO


Função original:

 var sort_by = function() { var fields = [].slice.call(arguments), n_fields = fields.length; return function(A,B) { var a, b, field, key, primer, reverse, result, i; for(i = 0; i < n_fields; i++) { result = 0; field = fields[i]; key = typeof field === 'string' ? field : field.name; a = A[key]; b = B[key]; if (typeof field.primer !== 'undefined'){ a = field.primer(a); b = field.primer(b); } reverse = (field.reverse) ? -1 : 1; if (ab) result = reverse * 1; if(result !== 0) break; } return result; } }; 

DEMO

para uma solução simples e não genérica para o seu problema exato:

 homes.sort( function(a, b) { if (a.city !== b.city) { return b.price - a.price; } return a.city > b.city ? 1 : -1; }); 

Eu fiz um classificador multi-resources bem genérico hoje. Você pode dar uma olhada no thenBy.js aqui: https://github.com/Teun/thenBy.js

Ele permite que você use o Array.sort padrão, mas com o estilo firstBy (). ThenBy (). ThenBy (). É muito menos código e complexidade do que as soluções postadas acima.

Aqui está uma abordagem funcional simples. Especifique ordem de sorting usando matriz. Prepend minus para especificar a ordem decrescente.

 var homes = [ {"h_id":"3", "city":"Dallas", "state":"TX","zip":"75201","price":"162500"}, {"h_id":"4","city":"Bevery Hills", "state":"CA", "zip":"90210", "price":"319250"}, {"h_id":"6", "city":"Dallas", "state":"TX", "zip":"75000", "price":"556699"}, {"h_id":"5", "city":"New York", "state":"NY", "zip":"00010", "price":"962500"} ]; homes.sort(fieldSorter(['city', '-price'])); // homes.sort(fieldSorter(['zip', '-state', 'price'])); // alternative function fieldSorter(fields) { return function (a, b) { return fields .map(function (o) { var dir = 1; if (o[0] === '-') { dir = -1; o=o.substring(1); } if (a[o] > b[o]) return dir; if (a[o] < b[o]) return -(dir); return 0; }) .reduce(function firstNonZeroValue (p,n) { return p ? p : n; }, 0); }; } 

Edit: no ES6 é ainda menor!

 "use strict"; const fieldSorter = (fields) => (a, b) => fields.map(o => { let dir = 1; if (o[0] === '-') { dir = -1; o=o.substring(1); } return a[o] > b[o] ? dir : a[o] < b[o] ? -(dir) : 0; }).reduce((p, n) => p ? p : n, 0); const homes = [{"h_id":"3", "city":"Dallas", "state":"TX","zip":"75201","price":162500}, {"h_id":"4","city":"Bevery Hills", "state":"CA", "zip":"90210", "price":319250},{"h_id":"6", "city":"Dallas", "state":"TX", "zip":"75000", "price":556699},{"h_id":"5", "city":"New York", "state":"NY", "zip":"00010", "price":962500}]; const sortedHomes = homes.sort(fieldSorter(['state', '-price'])); document.write('
' + JSON.stringify(sortedHomes, null, '\t') + '

')

A function a seguir permitirá que você classifique uma matriz de objects em uma ou várias propriedades, seja crescente (padrão) ou decrescente em cada propriedade, e permita que você escolha se deve ou não fazer comparações com distinção entre maiúsculas e minúsculas. Por padrão, essa function realiza classificações insensíveis a maiúsculas e minúsculas.

O primeiro argumento deve ser o array que contém os objects. O (s) argumento (s) subseqüente (s) deve (m) ser uma lista, separada por vírgulas, de cadeias de caracteres que referenciam as diferentes propriedades do object para classificar. O último argumento (que é opcional) é um booleano para escolher se deve ou não executar classificações sensíveis a maiúsculas e minúsculas – use true para classificações sensíveis a maiúsculas e minúsculas.

A function classificará cada propriedade / chave em ordem crescente por padrão. Se você quiser que uma chave específica seja ordenada em ordem decrescente, passe em um array neste formato: ['property_name', true] .

Aqui estão alguns exemplos de usos da function, seguidos de uma explicação (onde homes é um array contendo os objects):

objSort(homes, 'city') -> classificar por cidade (ascendente, maiúsculas e minúsculas)

objSort(homes, ['city', true]) -> classificar por cidade (descendente, maiúsculas e minúsculas)

objSort(homes, 'city', true) -> classificar por cidade e preço (crescente, sensível a maiúsculas)

objSort(homes, 'city', 'price') -> ordenar por cidade, em seguida, preço (ambos ascendentes, maiúsculas e minúsculas)

objSort(homes, 'city', ['price', true]) -> classificar por cidade (ascendente) e depois preço (decrescente), objSort(homes, 'city', ['price', true]) maiúsculas e minúsculas)

E sem mais delongas, aqui está a function:

 function objSort() { var args = arguments, array = args[0], case_sensitive, keys_length, key, desc, a, b, i; if (typeof arguments[arguments.length - 1] === 'boolean') { case_sensitive = arguments[arguments.length - 1]; keys_length = arguments.length - 1; } else { case_sensitive = false; keys_length = arguments.length; } return array.sort(function (obj1, obj2) { for (i = 1; i < keys_length; i++) { key = args[i]; if (typeof key !== 'string') { desc = key[1]; key = key[0]; a = obj1[args[i][0]]; b = obj2[args[i][0]]; } else { desc = false; a = obj1[args[i]]; b = obj2[args[i]]; } if (case_sensitive === false && typeof a === 'string') { a = a.toLowerCase(); b = b.toLowerCase(); } if (! desc) { if (a < b) return -1; if (a > b) return 1; } else { if (a > b) return -1; if (a < b) return 1; } } return 0; }); } //end of objSort() function 

E aqui estão alguns dados de amostra:

 var homes = [{ "h_id": "3", "city": "Dallas", "state": "TX", "zip": "75201", "price": 162500 }, { "h_id": "4", "city": "Bevery Hills", "state": "CA", "zip": "90210", "price": 1000000 }, { "h_id": "5", "city": "new york", "state": "NY", "zip": "00010", "price": 1000000 }, { "h_id": "6", "city": "Dallas", "state": "TX", "zip": "85000", "price": 300000 }, { "h_id": "7", "city": "New York", "state": "NY", "zip": "00020", "price": 345000 }]; 

Aqui está outro que talvez seja mais próximo da sua ideia para a syntax

 function sortObjects(objArray, properties /*, primers*/) { var primers = arguments[2] || {}; // primers are optional properties = properties.map(function(prop) { if( !(prop instanceof Array) ) { prop = [prop, 'asc'] } if( prop[1].toLowerCase() == 'desc' ) { prop[1] = -1; } else { prop[1] = 1; } return prop; }); function valueCmp(x, y) { return x > y ? 1 : x < y ? -1 : 0; } function arrayCmp(a, b) { var arr1 = [], arr2 = []; properties.forEach(function(prop) { var aValue = a[prop[0]], bValue = b[prop[0]]; if( typeof primers[prop[0]] != 'undefined' ) { aValue = primers[prop[0]](aValue); bValue = primers[prop[0]](bValue); } arr1.push( prop[1] * valueCmp(aValue, bValue) ); arr2.push( prop[1] * valueCmp(bValue, aValue) ); }); return arr1 < arr2 ? -1 : 1; } objArray.sort(function(a, b) { return arrayCmp(a, b); }); } // just for fun use this to reverse the city name when sorting function demoPrimer(str) { return str.split('').reverse().join(''); } // Example sortObjects(homes, ['city', ['price', 'desc']], {city: demoPrimer}); 

Demonstração: http://jsfiddle.net/Nq4dk/2/


Edit: Apenas por diversão, aqui está uma variação que apenas leva uma string parecida com sql, para que você possa fazer sortObjects(homes, "city, price desc")

 function sortObjects(objArray, properties /*, primers*/) { var primers = arguments[2] || {}; properties = properties.split(/\s*,\s*/).map(function(prop) { prop = prop.match(/^([^\s]+)(\s*desc)?/i); if( prop[2] && prop[2].toLowerCase() === 'desc' ) { return [prop[1] , -1]; } else { return [prop[1] , 1]; } }); function valueCmp(x, y) { return x > y ? 1 : x < y ? -1 : 0; } function arrayCmp(a, b) { var arr1 = [], arr2 = []; properties.forEach(function(prop) { var aValue = a[prop[0]], bValue = b[prop[0]]; if( typeof primers[prop[0]] != 'undefined' ) { aValue = primers[prop[0]](aValue); bValue = primers[prop[0]](bValue); } arr1.push( prop[1] * valueCmp(aValue, bValue) ); arr2.push( prop[1] * valueCmp(bValue, aValue) ); }); return arr1 < arr2 ? -1 : 1; } objArray.sort(function(a, b) { return arrayCmp(a, b); }); } 

Este é um truque completo, mas eu acho que agrega valor a esta questão, porque é basicamente uma function de biblioteca que você pode usar fora da checkbox.

Se o seu código tiver access a uma biblioteca compatível com lodash ou lodash, como underscore , você poderá usar o método _.sortBy . O snippet abaixo é copiado diretamente da documentação da lodash .

Os resultados comentados nos exemplos parecem retornar matrizes de matrizes, mas isso é apenas mostrar a ordem e não os resultados reais que são uma matriz de objects.

 var users = [ { 'user': 'fred',   'age': 48 }, { 'user': 'barney', 'age': 36 }, { 'user': 'fred',   'age': 40 }, { 'user': 'barney', 'age': 34 } ]; _.sortBy(users, [function(o) { return o.user; }]); // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] _.sortBy(users, ['user', 'age']); // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]] 

Mais simples:

 var someArray = [...]; function generateSortFn(props) { return function (a, b) { for (var i = 0; i < props.length; i++) { var prop = props[i]; var name = prop.name; var reverse = prop.reverse; if (a[name] < b[name]) return reverse ? 1 : -1; if (a[name] > b[name]) return reverse ? -1 : 1; } return 0; }; }; someArray.sort(generateSortFn([{name: 'prop1', reverse: true}, {name: 'prop2'}])); 

Aqui está uma versão genérica da solução @ Snowburnt:

 var sortarray = [{field:'city', direction:'asc'}, {field:'price', direction:'desc'}]; array.sort(function(a,b){ for(var i=0; i b[sortarray[i].field] ? 1 : 0; if (sortarray[i].direction == "desc") { retval = retval * -1; } if (retval !== 0) { return retval; } } } }) 

Isso é baseado em uma rotina de sorting que estou usando. Eu não testei este código específico, então pode haver erros, mas você entendeu. A idéia é classificar com base no primeiro campo que indica uma diferença e, em seguida, parar e ir para o próximo registro. Portanto, se você estiver classificando por três campos e o primeiro campo na comparação for suficiente para determinar a ordem de sorting dos dois registros que estão sendo classificados, retorne esse resultado de sorting e vá para o próximo registro.

Eu testei (na verdade com lógica de sorting um pouco mais complexa) em 5000 registros e fiz isso em um piscar de olhos. Se você estiver realmente carregando mais de 1.000 registros para o cliente, provavelmente deverá estar usando a sorting e a filtragem do lado do servidor.

Esse código não está lidando com a diferenciação de maiúsculas e minúsculas, mas deixo para o leitor lidar com essa modificação trivial.

Eu gosto da abordagem do SnowBurnt, mas ele precisa de um ajuste para testar a equivalência na cidade e não uma diferença.

 homes.sort( function(a,b){ if (a.city==b.city){ return (b.price-a.price); } else { return (a.city-b.city); } }); 

Aqui está a minha solução baseada no idioma transformado Schwartziano , espero que você ache útil.

 function sortByAttribute(array, ...attrs) { // generate an array of predicate-objects contains // property getter, and descending indicator let predicates = attrs.map(pred => { let descending = pred.charAt(0) === '-' ? -1 : 1; pred = pred.replace(/^-/, ''); return { getter: o => o[pred], descend: descending }; }); // schwartzian transform idiom implementation. aka: "decorate-sort-undecorate" return array.map(item => { return { src: item, compareValues: predicates.map(predicate => predicate.getter(item)) }; }) .sort((o1, o2) => { let i = -1, result = 0; while (++i < predicates.length) { if (o1.compareValues[i] < o2.compareValues[i]) result = -1; if (o1.compareValues[i] > o2.compareValues[i]) result = 1; if (result *= predicates[i].descend) break; } return result; }) .map(item => item.src); } 

Veja um exemplo de como usá-lo:

 let games = [ { name: 'Pako', rating: 4.21 }, { name: 'Hill Climb Racing', rating: 3.88 }, { name: 'Angry Birds Space', rating: 3.88 }, { name: 'Badland', rating: 4.33 } ]; // sort by one attribute console.log(sortByAttribute(games, 'name')); // sort by mupltiple attributes console.log(sortByAttribute(games, '-rating', 'name')); 

Outra maneira

 var homes = [ {"h_id":"3", "city":"Dallas", "state":"TX", "zip":"75201", "price":"162500"}, {"h_id":"4", "city":"Bevery Hills", "state":"CA", "zip":"90210", "price":"319250"}, {"h_id":"6", "city":"Dallas", "state":"TX", "zip":"75000", "price":"556699"}, {"h_id":"5", "city":"New York", "state":"NY", "zip":"00010", "price":"962500"} ]; function sortBy(ar) { return ar.sort((a, b) => a.city === b.city ? b.price.toString().localeCompare(a.price) : a.city.toString().localeCompare(b.city)); } console.log(sortBy(homes)); 

Você poderia usar uma abordagem de sorting encadeada, tomando o delta de valores até atingir um valor diferente de zero.

 var data = [{ h_id: "3", city: "Dallas", state: "TX", zip: "75201", price: "162500" }, { h_id: "4", city: "Bevery Hills", state: "CA", zip: "90210", price: "319250" }, { h_id: "6", city: "Dallas", state: "TX", zip: "75000", price: "556699" }, { h_id: "5", city: "New York", state: "NY", zip: "00010", price: "962500" }]; data.sort(function (a, b) { return a.city.localeCompare(b.city) || b.price - a.price; }); console.log(data); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 
 function sortMultiFields(prop){ return function(a,b){ for(i=0;i b[field1]) return x; else if(a[field1] < b[field1]) return -x; } } } 

Como usar (coloque - (menos) sinal antes de campo se você quiser classificar em campo específico de ordem decrescente)

 homes.sort(sortMultiFields(["city","-price"])); 

Usando a function acima, você pode classificar qualquer matriz json com vários campos. Não há necessidade de mudar o corpo da function

Aqui está uma maneira extensível de classificar por vários campos.

 homes.sort(function(left, right) { var city_order = left.city.localeCompare(right.city); var price_order = parseInt(left.price) - parseInt(right.price); return city_order || -price_order; }); 

Notas

  • a.localeCompare(b) é universalmente suportado e retorna -1,0,1 se a , a==b , a>b respectivamente.
  • Subtração funciona em campos numéricos.
  • || na última linha dá prioridade à city sobre o price .
  • Negar para inverter a ordem em qualquer campo, como em -price_order
  • Comparação de datas , var date_order = new Date(left.date) - new Date(right.date); funciona como numéricos porque a matemática das datas se transforma em milissegundos desde 1970.
  • Adicione campos na cadeia ou, return city_order || -price_order || date_order; return city_order || -price_order || date_order;
 homes.sort(function(a,b) { return a.city - b.city } ); homes.sort(function(a,b){ if (a.city==b.city){ return parseFloat(b.price) - parseFloat(a.price); } else { return 0; } }); 

Aqui ‘AffiliateDueDate’ e ‘Title’ são colunas, ambas são classificadas em ordem crescente.

 array.sort(function(a, b) { if (a.AffiliateDueDate > b.AffiliateDueDate ) return 1; else if (a.AffiliateDueDate < b.AffiliateDueDate ) return -1; else if (a.Title > b.Title ) return 1; else if (a.Title < b.Title ) return -1; else return 0; }) 

Classificando dois campos de data e um exemplo de campo numérico:

 var generic_date = new Date(2070, 1, 1); checkDate = function(date) { return Date.parse(date) ? new Date(date): generic_date; } function sortData() { data.sort(function(a,b){ var deltaEnd = checkDate(b.end) - checkDate(a.end); if(deltaEnd) return deltaEnd; var deltaRank = a.rank - b.rank; if (deltaRank) return deltaRank; var deltaStart = checkDate(b.start) - checkDate(a.start); if(deltaStart) return deltaStart; return 0; }); } 

http://jsfiddle.net/hcWgf/57/

 function sort(data, orderBy) { orderBy = Array.isArray(orderBy) ? orderBy : [orderBy]; return data.sort((a, b) => { for (let i = 0, size = orderBy.length; i < size; i++) { const key = Object.keys(orderBy[i])[0], o = orderBy[i][key], valueA = a[key], valueB = b[key]; if (!(valueA || valueB)) { console.error("the objects from the data passed does not have the key '" + key + "' passed on sort!"); return []; } if (+valueA === +valueA) { return o.toLowerCase() === 'desc' ? valueB - valueA : valueA - valueB; } else { if (valueA.localeCompare(valueB) > 0) { return o.toLowerCase() === 'desc' ? -1 : 1; } else if (valueA.localeCompare(valueB) < 0) { return o.toLowerCase() === 'desc' ? 1 : -1; } } } }); } 

Usando:

 sort(homes, [{city : 'asc'}, {price: 'desc'}]) 
 var homes = [ {"h_id":"3", "city":"Dallas", "state":"TX", "zip":"75201", "price":"162500"}, {"h_id":"4", "city":"Bevery Hills", "state":"CA", "zip":"90210", "price":"319250"}, {"h_id":"6", "city":"Dallas", "state":"TX", "zip":"75000", "price":"556699"}, {"h_id":"5", "city":"New York", "state":"NY", "zip":"00010", "price":"962500"} ]; function sort(data, orderBy) { orderBy = Array.isArray(orderBy) ? orderBy : [orderBy]; return data.sort((a, b) => { for (let i = 0, size = orderBy.length; i < size; i++) { const key = Object.keys(orderBy[i])[0], o = orderBy[i][key], valueA = a[key], valueB = b[key]; if (!(valueA || valueB)) { console.error("the objects from the data passed does not have the key '" + key + "' passed on sort!"); return []; } if (+valueA === +valueA) { return o.toLowerCase() === 'desc' ? valueB - valueA : valueA - valueB; } else { if (valueA.localeCompare(valueB) > 0) { return o.toLowerCase() === 'desc' ? -1 : 1; } else if (valueA.localeCompare(valueB) < 0) { return o.toLowerCase() === 'desc' ? 1 : -1; } } } }); } console.log(sort(homes, [{city : 'asc'}, {price: 'desc'}])); 

Adaptação da resposta de @chriskelly.


A maioria das respostas ignora que o preço não será classificado corretamente se o valor estiver entre dez e menos e mais de um milhão. A resaon sendo JS classifica por ordem alfabética. Foi respondido muito bem aqui, porque não pode JavaScript classificar “5, 10, 1” e aqui Como classificar uma matriz de inteiros corretamente .

Em última análise, temos que fazer alguma avaliação se o campo ou o nó que estamos classificando for um número. Eu não estou dizendo que usando parseInt() neste caso é a resposta correta, os resultados classificados são mais importantes.

 var homes = [{ "h_id": "2", "city": "Dallas", "state": "TX", "zip": "75201", "price": "62500" }, { "h_id": "1", "city": "Dallas", "state": "TX", "zip": "75201", "price": "62510" }, { "h_id": "3", "city": "Dallas", "state": "TX", "zip": "75201", "price": "162500" }, { "h_id": "4", "city": "Bevery Hills", "state": "CA", "zip": "90210", "price": "319250" }, { "h_id": "6", "city": "Dallas", "state": "TX", "zip": "75000", "price": "556699" }, { "h_id": "5", "city": "New York", "state": "NY", "zip": "00010", "price": "962500" }]; homes.sort(fieldSorter(['price'])); // homes.sort(fieldSorter(['zip', '-state', 'price'])); // alternative function fieldSorter(fields) { return function(a, b) { return fields .map(function(o) { var dir = 1; if (o[0] === '-') { dir = -1; o = o.substring(1); } if (!parseInt(a[o]) && !parseInt(b[o])) { if (a[o] > b[o]) return dir; if (a[o] < b[o]) return -(dir); return 0; } else { return dir > 0 ? a[o] - b[o] : b[o] - a[o]; } }) .reduce(function firstNonZeroValue(p, n) { return p ? p : n; }, 0); }; } document.getElementById("output").innerHTML = '
' + JSON.stringify(homes, null, '\t') + '

';

 

Uau, existem algumas soluções complexas aqui. Tão complexo que decidi criar algo mais simples, mas também bastante poderoso. Aqui está;

 function sortByPriority(data, priorities) { if (priorities.length == 0) { return data; } const nextPriority = priorities[0]; const remainingPriorities = priorities.slice(1); const matched = data.filter(item => item.hasOwnProperty(nextPriority)); const remainingData = data.filter(item => !item.hasOwnProperty(nextPriority)); return sortByPriority(matched, remainingPriorities) .sort((a, b) => (a[nextPriority] > b[nextPriority]) ? 1 : -1) .concat(sortByPriority(remainingData, remainingPriorities)); } 

E aqui está um exemplo de como você o usa.

 const data = [ { id: 1, mediumPriority: 'bbb', lowestPriority: 'ggg' }, { id: 2, highestPriority: 'bbb', mediumPriority: 'ccc', lowestPriority: 'ggg' }, { id: 3, mediumPriority: 'aaa', lowestPriority: 'ggg' }, ]; const priorities = [ 'highestPriority', 'mediumPriority', 'lowestPriority' ]; const sorted = sortByPriority(data, priorities); 

Isso primeiro classificará pela precedência dos atributos e, em seguida, pelo valor dos atributos.

Como sobre esta solução simples:

 const sortCompareByCityPrice = (a, b) => { let comparison = 0 // sort by first criteria if (a.city > b.city) { comparison = 1 } else if (a.city < b.city) { comparison = -1 } // If still 0 then sort by second criteria descending if (comparison === 0) { if (parseInt(a.price) > parseInt(b.price)) { comparison = -1 } else if (parseInt(a.price) < parseInt(b.price)) { comparison = 1 } } return comparison } 

Com base nesta pergunta javascript sort array por campos múltiplos (número)