Classificando uma matriz de objetos por valores de propriedade

1334

Eu tenho os seguintes objetos usando AJAX e os armazenei em uma matriz:

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": "5",
        "city": "New York",
        "state": "NY",
        "zip": "00010",
        "price": "962500"
    }
];

Como crio uma função para classificar os objetos pela pricepropriedade em ordem crescente ou decrescente usando apenas JavaScript?

TomHankers
fonte
a maneira mais rápida é usar o módulo de matriz de classificação isomórfica que funciona nativamente no navegador e no nó, suportando qualquer tipo de entrada, campos calculados e ordens de classificação personalizadas.
Lloyd

Respostas:

1674

Classifique as casas por preço em ordem crescente:

homes.sort(function(a, b) {
    return parseFloat(a.price) - parseFloat(b.price);
});

Ou após a versão ES6:

homes.sort((a, b) => parseFloat(a.price) - parseFloat(b.price));

Alguma documentação pode ser encontrada aqui .

Stobor
fonte
184
Você pode usar string1.localeCompare(string2)para comparação de string
bradvido
62
Lembre-se de que não diferencialocaleCompare() maiúsculas de minúsculas . Se você quer distinção entre maiúsculas e minúsculas, pode usar (string1 > string2) - (string1 < string2). Os valores booleanos são coagidos aos números inteiros 0 e 1 para calcular a diferença.
Don Kirkby
2
Obrigado pela atualização, @Pointy, não me lembro de ter encontrado esse problema, mas talvez o comportamento tenha mudado nos últimos dois anos. Independentemente disso, a localeCompare()documentação mostra que você pode indicar explicitamente se deseja distinção entre maiúsculas e minúsculas, classificação numérica e outras opções.
Don Kirkby
2
@ sg28 Acho que você não entendeu a explicação MDN. Não diz que a função de classificação não é confiável , diz que não é estável . Entendo por que isso pode ser confuso, mas isso não significa que não é adequado para uso. No contexto de algoritmos de classificação, o termo estável tem um significado específico - que elementos "iguais" na lista são classificados na mesma ordem que na entrada . Isso não tem nenhuma relação com a ideia de código que é instável (ou seja, ainda não está pronta para uso).
Stobor
1
Se você deseja classificar por valores de sequência específicos, por exemplo, por cidade, pode usar: this.homes.sort ((current, next) => {return current.city.localeCompare (next.city)});
Jorge Valvert
675

Aqui está uma versão mais flexível, que permite criar funções de classificação reutilizáveis ​​e classificar por qualquer campo.

const sort_by = (field, reverse, primer) => {

  const key = primer ?
    function(x) {
      return primer(x[field])
    } :
    function(x) {
      return x[field]
    };

  reverse = !reverse ? 1 : -1;

  return function(a, b) {
    return a = key(a), b = key(b), reverse * ((a > b) - (b > a));
  }
}


//Now you can sort by any field at will...

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:"5",city:"New York",state:"NY",zip:"00010",price:"962500"}];

// Sort by price high to low
console.log(homes.sort(sort_by('price', true, parseInt)));

// Sort by city, case-insensitive, A-Z
console.log(homes.sort(sort_by('city', false, (a) =>  a.toUpperCase()
)));

Tríptico
fonte
7
nickb - você está interpretando mal o código. sort_byé executado em O (1) e retorna uma função usada pela classificação interna (O (N log N)) para comparar itens em uma lista. A complexidade total é O (n log n) * O (1) que se reduz a O (n log n), ou o mesmo que uma classificação rápida.
Triptych
1
Um problema que tenho com isto é que com reverso = false, ele irá classificar números como 1,2,3,4 ... mas Cordas como z, y, x ...
Abby
4
Um pequeno aprimoramento:var key = primer ? function (x) { return primer(x[field]); } : function (x) { return x[field]; }
ErikE 07/08/12
6
Embora [1,-1][+!!reverse]pareça legal, é uma coisa horrível de se fazer. Se um usuário não puder chamar seu método corretamente, castigue-o, não tente entendê-lo de alguma forma, não importa o quê.
Ingo Bürk
2
Não seria melhor preparar os dados de origem, isso causaria uma análise consecutiva quando claramente os dados de origem precisassem de alguns ajustes.
Gerrit Brink
134

Para classificá-lo, você precisa criar uma função comparadora usando dois argumentos. Em seguida, chame a função de classificação com essa função comparadora da seguinte maneira:

// a and b are object elements of your array
function mycomparator(a,b) {
  return parseInt(a.price, 10) - parseInt(b.price, 10);
}
homes.sort(mycomparator);

Se você deseja classificar ascendente, alterne as expressões de cada lado do sinal de menos.

Ricardo Marimon
fonte
3
E aqui está uma referência que realmente explica o tópico em vez de dizer "é muito complicado, você não vai entender mesmo": developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Roland Illig
51

para classificação de strings, caso alguém precise,

const dataArr = {

  "hello": [{
    "id": 114,
    "keyword": "zzzzzz",
    "region": "Sri Lanka",
    "supportGroup": "administrators",
    "category": "Category2"
  }, {
    "id": 115,
    "keyword": "aaaaa",
    "region": "Japan",
    "supportGroup": "developers",
    "category": "Category2"
  }]

};
const sortArray = dataArr['hello'];

console.log(sortArray.sort((a, b) => {
  if (a.region < b.region)
    return -1;
  if (a.region > b.region)
    return 1;
  return 0;
}));

Ishan Liyanage
fonte
38

Se você possui um navegador compatível com ES6, pode usar:

A diferença entre ordem de classificação crescente e decrescente é o sinal do valor retornado por sua função de comparação:

var ascending = homes.sort((a, b) => Number(a.price) - Number(b.price));
var descending = homes.sort((a, b) => Number(b.price) - Number(a.price));

Aqui está um trecho de código de trabalho:

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": "5",
  "city": "New York",
  "state": "NY",
  "zip": "00010",
  "price": "962500"
}];

homes.sort((a, b) => Number(a.price) - Number(b.price));
console.log("ascending", homes);

homes.sort((a, b) => Number(b.price) - Number(a.price));
console.log("descending", homes);

Stephen Quan
fonte
22

Você quer classificá-lo em Javascript, certo? O que você quer é a sort()função . Nesse caso, você precisa escrever uma função comparadora e passá-la para sort()algo assim:

function comparator(a, b) {
    return parseInt(a["price"], 10) - parseInt(b["price"], 10);
}

var json = { "homes": [ /* your previous data */ ] };
console.log(json["homes"].sort(comparator));

Seu comparador pega um de cada um dos hashes aninhados dentro da matriz e decide qual deles é mais alto, verificando o campo "preço".

Tim Gilbert
fonte
21

Eu recomendo o GitHub: Array sortBy - uma melhor implementação de sortBymétodo que usa a transformação Schwartziana

Mas, por enquanto, vamos tentar essa abordagem Gist: sortBy-old.js .
Vamos criar um método para classificar matrizes capazes de organizar objetos por alguma propriedade.

Criando a função de classificação

var sortBy = (function () {
  var toString = Object.prototype.toString,
      // default parser function
      parse = function (x) { return x; },
      // gets the item to be sorted
      getItem = function (x) {
        var isObject = x != null && typeof x === "object";
        var isProp = isObject && this.prop in x;
        return this.parser(isProp ? x[this.prop] : x);
      };

  /**
   * Sorts an array of elements.
   *
   * @param  {Array} array: the collection to sort
   * @param  {Object} cfg: the configuration options
   * @property {String}   cfg.prop: property name (if it is an Array of objects)
   * @property {Boolean}  cfg.desc: determines whether the sort is descending
   * @property {Function} cfg.parser: function to parse the items to expected type
   * @return {Array}
   */
  return function sortby (array, cfg) {
    if (!(array instanceof Array && array.length)) return [];
    if (toString.call(cfg) !== "[object Object]") cfg = {};
    if (typeof cfg.parser !== "function") cfg.parser = parse;
    cfg.desc = !!cfg.desc ? -1 : 1;
    return array.sort(function (a, b) {
      a = getItem.call(cfg, a);
      b = getItem.call(cfg, b);
      return cfg.desc * (a < b ? -1 : +(a > b));
    });
  };

}());

Configurando dados não classificados

var data = [
  {date: "2011-11-14T16:30:43Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T17:22:59Z", quantity: 2, total: 90,  tip: 0,   type: "Tab"},
  {date: "2011-11-14T16:28:54Z", quantity: 1, total: 300, tip: 200, type: "visa"},
  {date: "2011-11-14T16:53:41Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T16:48:46Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T17:25:45Z", quantity: 2, total: 200, tip: 0,   type: "cash"},
  {date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa"},
  {date: "2011-11-14T16:58:03Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T16:20:19Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-14T17:07:21Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0,   type: "Cash"}
];

Usando isso

Organize a matriz, "date"conformeString

// sort by @date (ascending)
sortBy(data, { prop: "date" });

// expected: first element
// { date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab" }

// expected: last element
// { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa"}

Se você deseja ignorar distinção entre maiúsculas e minúsculas, defina o parserretorno de chamada:

// sort by @type (ascending) IGNORING case-sensitive
sortBy(data, {
    prop: "type",
    parser: (t) => t.toUpperCase()
});

// expected: first element
// { date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0, type: "Cash" }

// expected: last element
// { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa" }

Se você deseja converter o "date"campo como Datetipo:

// sort by @date (descending) AS Date object
sortBy(data, {
    prop: "date",
    desc: true,
    parser: (d) => new Date(d)
});

// expected: first element
// { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa"}

// expected: last element
// { date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab" }

Aqui você pode jogar com o código: jsbin.com/lesebi

Graças a @Ozesh por seus comentários, o problema relacionado às propriedades com valores falsos foi corrigido.

jherax
fonte
Isso parece ser interrompido quando um campo é nulo.
TSNev 25/08/16
Caso esteja classificando números e encontrando um '0' entre a matriz de objetos, você pode perceber que o código acima é quebrado. Aqui está uma solução rápida para isso: var checkNaN = function (value) { return Number.isNaN(Number(value)) ? 0 : value; } seguido por: return function (array, o) { .... a = _getItem.call (o, a); a = checkNaN (a); b = _getItem.call (o, b); b = checkNaN (b); retornar o.desc * (a <b? -1: + (a> b)); });
Ozesh
18

Use lodash.sortBy , (instruções usando commonjs, você também pode colocar o script include-tag para o cdn na parte superior do seu html)

var sortBy = require('lodash.sortby');
// or
sortBy = require('lodash').sortBy;

Ordem decrescente

var descendingOrder = sortBy( homes, 'price' ).reverse();

Ordem ascendente

var ascendingOrder = sortBy( homes, 'price' );
Evan Carroll
fonte
1
Ouconst sortBy = require('lodash/sortBy'); let calendars = sortBy(calendarListResponse.items, cal => cal.summary);
mpen
Não tenho certeza se loadash mudou recentemente até agora seu chamado OrderByimport { orderBy } from 'lodash'; ... ... return orderBy ( rows, 'fieldName' ).reverse();
montelof 08/12/16
8

Isso poderia ter sido alcançado através de uma função de classificação valueof () simples de uma linha . Execute o snippet de código abaixo para ver a demonstração.

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": "5",
        "city": "New York",
        "state": "NY",
        "zip": "00010",
        "price": "962500"
    }
];

console.log("To sort descending/highest first, use operator '<'");

homes.sort(function(a,b) { return a.price.valueOf() < b.price.valueOf();});

console.log(homes);

console.log("To sort ascending/lowest first, use operator '>'");

homes.sort(function(a,b) { return a.price.valueOf() > b.price.valueOf();});

console.log(homes);

Ajay Singh
fonte
8

Estou um pouco atrasado para a festa, mas abaixo está minha lógica para classificar.

function getSortedData(data, prop, isAsc) {
    return data.sort((a, b) => {
        return (a[prop] < b[prop] ? -1 : 1) * (isAsc ? 1 : -1)
    });
}
Santosh
fonte
6

Embora eu esteja ciente de que o OP queria classificar uma matriz de números, essa pergunta foi marcada como a resposta para perguntas semelhantes sobre seqüências de caracteres. Por esse motivo, as respostas acima não consideram a classificação de uma matriz de texto em que a caixa é importante. A maioria das respostas pega os valores da string e os converte em maiúsculas / minúsculas e, em seguida, classifica de uma maneira ou de outra. Os requisitos aos quais eu aderi são simples:

  • Classificar alfabeticamente AZ
  • Os valores em maiúsculas da mesma palavra devem vir antes dos valores em minúsculas
  • Os mesmos valores de letra (A / a, B / b) devem ser agrupados

O que espero é que [ A, a, B, b, C, c ]as respostas acima retornem A, B, C, a, b, c. Na verdade, eu cocei minha cabeça por mais tempo do que queria (e é por isso que estou postando isso na esperança de que ajude pelo menos uma outra pessoa). Enquanto dois usuários mencionam a localeComparefunção nos comentários para a resposta marcada, não vi isso até depois de me deparar com a função enquanto procurava. Depois de ler a documentação String.prototype.localeCompare (), consegui fazer isso:

var values = [ "Delta", "charlie", "delta", "Charlie", "Bravo", "alpha", "Alpha", "bravo" ];
var sorted = values.sort((a, b) => a.localeCompare(b, undefined, { caseFirst: "upper" }));
// Result: [ "Alpha", "alpha", "Bravo", "bravo", "Charlie", "charlie", "Delta", "delta" ]

Isso informa à função para classificar valores em maiúsculas antes de valores em minúsculas. O segundo parâmetro na localeComparefunção é definir o código do idioma, mas se você o deixar, undefinedele descobrirá automaticamente o código do idioma para você.

Isso funciona da mesma forma para classificar uma matriz de objetos:

var values = [
    { id: 6, title: "Delta" },
    { id: 2, title: "charlie" },
    { id: 3, title: "delta" },
    { id: 1, title: "Charlie" },
    { id: 8, title: "Bravo" },
    { id: 5, title: "alpha" },
    { id: 4, title: "Alpha" },
    { id: 7, title: "bravo" }
];
var sorted = values
    .sort((a, b) => a.title.localeCompare(b.title, undefined, { caseFirst: "upper" }));
Mitchell Skurnik
fonte
5

Você pode usar o sortmétodo JavaScript com uma função de retorno de chamada:

function compareASC(homeA, homeB)
{
    return parseFloat(homeA.price) - parseFloat(homeB.price);
}

function compareDESC(homeA, homeB)
{
    return parseFloat(homeB.price) - parseFloat(homeA.price);
}

// Sort ASC
homes.sort(compareASC);

// Sort DESC
homes.sort(compareDESC);
John G
fonte
4

Aqui está um ponto culminante de todas as respostas acima.

Validação do Fiddle: http://jsfiddle.net/bobberino/4qqk3/

var sortOn = function (arr, prop, reverse, numeric) {

    // Ensure there's a property
    if (!prop || !arr) {
        return arr
    }

    // Set up sort function
    var sort_by = function (field, rev, primer) {

        // Return the required a,b function
        return function (a, b) {

            // Reset a, b to the field
            a = primer(a[field]), b = primer(b[field]);

            // Do actual sorting, reverse as needed
            return ((a < b) ? -1 : ((a > b) ? 1 : 0)) * (rev ? -1 : 1);
        }

    }

    // Distinguish between numeric and string to prevent 100's from coming before smaller
    // e.g.
    // 1
    // 20
    // 3
    // 4000
    // 50

    if (numeric) {

        // Do sort "in place" with sort_by function
        arr.sort(sort_by(prop, reverse, function (a) {

            // - Force value to a string.
            // - Replace any non numeric characters.
            // - Parse as float to allow 0.02 values.
            return parseFloat(String(a).replace(/[^0-9.-]+/g, ''));

        }));
    } else {

        // Do sort "in place" with sort_by function
        arr.sort(sort_by(prop, reverse, function (a) {

            // - Force value to string.
            return String(a).toUpperCase();

        }));
    }


}
prumo
fonte
você pode explicar qual é o significado de ter * (rev? -1: 1);
TechTurtle
Isso é para inverter a ordem (ascendente vs descendente), a parte rev apenas vira resultados normais quando o argumento rev é verdadeiro. Caso contrário, apenas multiplicará por 1, o que não fará nada, quando definido, multiplicará o resultado por -1, invertendo o resultado.
22917 bob
3

Para classificar uma matriz, você deve definir uma função comparadora. Essa função sempre será diferente no padrão ou ordem de classificação desejada (por exemplo, ascendente ou descendente).

Vamos criar algumas funções que classifiquem uma matriz ascendente ou descendente e que contenham objeto, sequência ou valores numéricos.

function sorterAscending(a,b) {
    return a-b;
}

function sorterDescending(a,b) {
    return b-a;
}

function sorterPriceAsc(a,b) {
    return parseInt(a['price']) - parseInt(b['price']);
}

function sorterPriceDes(a,b) {
    return parseInt(b['price']) - parseInt(b['price']);
}

Classifique os números (em ordem alfabética e crescente):

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort();

Classifique os números (em ordem alfabética e descendente):

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort();
fruits.reverse();

Classificar números (numericamente e crescente):

var points = [40,100,1,5,25,10];
points.sort(sorterAscending());

Classificar números (numericamente e decrescente):

var points = [40,100,1,5,25,10];
points.sort(sorterDescending());

Como acima, use o método sorterPriceAsc e sorterPriceDes com sua matriz com a chave desejada.

homes.sort(sorterPriceAsc()) or homes.sort(sorterPriceDes())
Lalit Kumar Maurya
fonte
3

Também trabalhei com algum tipo de classificação e vários campos:

arr = [
    {type:'C', note:834},
    {type:'D', note:732},
    {type:'D', note:008},
    {type:'F', note:474},
    {type:'P', note:283},
    {type:'P', note:165},
    {type:'X', note:173},
    {type:'Z', note:239},
];

arr.sort(function(a,b){        
    var _a = ((a.type==='C')?'0':(a.type==='P')?'1':'2');
    _a += (a.type.localeCompare(b.type)===-1)?'0':'1';
    _a += (a.note>b.note)?'1':'0';
    var _b = ((b.type==='C')?'0':(b.type==='P')?'1':'2');
    _b += (b.type.localeCompare(a.type)===-1)?'0':'1';
    _b += (b.note>a.note)?'1':'0';
    return parseInt(_a) - parseInt(_b);
});

Resultado

[
    {"type":"C","note":834},
    {"type":"P","note":165},
    {"type":"P","note":283},
    {"type":"D","note":8},
    {"type":"D","note":732},
    {"type":"F","note":474},
    {"type":"X","note":173},
    {"type":"Z","note":239}
]
Rodolfo Jorge Nemer Nogueira
fonte
3

Embora seja um exagero apenas para classificar uma única matriz, essa função de protótipo permite classificar as matrizes Javascript por qualquer chave, em ordem crescente ou decrescente, incluindo chaves aninhadas , usando a dotsintaxe.

(function(){
    var keyPaths = [];

    var saveKeyPath = function(path) {
        keyPaths.push({
            sign: (path[0] === '+' || path[0] === '-')? parseInt(path.shift()+1) : 1,
            path: path
        });
    };

    var valueOf = function(object, path) {
        var ptr = object;
        for (var i=0,l=path.length; i<l; i++) ptr = ptr[path[i]];
        return ptr;
    };

    var comparer = function(a, b) {
        for (var i = 0, l = keyPaths.length; i < l; i++) {
            aVal = valueOf(a, keyPaths[i].path);
            bVal = valueOf(b, keyPaths[i].path);
            if (aVal > bVal) return keyPaths[i].sign;
            if (aVal < bVal) return -keyPaths[i].sign;
        }
        return 0;
    };

    Array.prototype.sortBy = function() {
        keyPaths = [];
        for (var i=0,l=arguments.length; i<l; i++) {
            switch (typeof(arguments[i])) {
                case "object": saveKeyPath(arguments[i]); break;
                case "string": saveKeyPath(arguments[i].match(/[+-]|[^.]+/g)); break;
            }
        }
        return this.sort(comparer);
    };    
})();

Uso:

var data = [
    { name: { first: 'Josh', last: 'Jones' }, age: 30 },
    { name: { first: 'Carlos', last: 'Jacques' }, age: 19 },
    { name: { first: 'Carlos', last: 'Dante' }, age: 23 },
    { name: { first: 'Tim', last: 'Marley' }, age: 9 },
    { name: { first: 'Courtney', last: 'Smith' }, age: 27 },
    { name: { first: 'Bob', last: 'Smith' }, age: 30 }
]

data.sortBy('age'); // "Tim Marley(9)", "Carlos Jacques(19)", "Carlos Dante(23)", "Courtney Smith(27)", "Josh Jones(30)", "Bob Smith(30)"

Classificação por propriedades aninhadas com sintaxe de ponto ou sintaxe de matriz:

data.sortBy('name.first'); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"
data.sortBy(['name', 'first']); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"

Classificando por várias chaves:

data.sortBy('name.first', 'age'); // "Bob Smith(30)", "Carlos Jacques(19)", "Carlos Dante(23)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"
data.sortBy('name.first', '-age'); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"

Você pode bifurcar o repositório: https://github.com/eneko/Array.sortBy

Eneko Alonso
fonte
Eu gosto muito desta resposta por causa da sortBysintaxe concisa. Simples de usar, mesmo com campos aninhados, mantendo excelente legibilidade do código. Obrigado!
Manfred Urban
3

Com o ECMAScript 6, a resposta da StoBor pode ser ainda mais concisa:

homes.sort((a, b) => a.price - b.price)
CracyD
fonte
3

Ordem decrescente de preço:

homes.sort((x,y) => {return y.price - x.price})

Ordem crescente de preço:

homes.sort((x,y) => {return x.price - y.price})
Arushi Bajpai
fonte
2

Se você usa Underscore.js , tente sortBy:

// price is of an integer type
_.sortBy(homes, "price"); 

// price is of a string type
_.sortBy(homes, function(home) {return parseInt(home.price);}); 
Vitalii Fedorenko
fonte
2

Aqui está uma versão ligeiramente modificada da implementação elegante do livro "JavaScript: The Good Parts".

NOTA : Esta versão do byé estável . Ele preserva a ordem da primeira classificação enquanto executa a próxima classificação em cadeia.

Eu adicionei isAscendingparâmetro a ele. Também o converteu em ES6padrões e peças boas "mais recentes", conforme recomendado pelo autor.

Você pode classificar em ordem crescente e decrescente e em cadeia por várias propriedades.

const by = function (name, minor, isAscending=true) {
    const reverseMutliplier = isAscending ? 1 : -1;
    return function (o, p) {
        let a, b;
        let result;
        if (o && p && typeof o === "object" && typeof p === "object") {
            a = o[name];
            b = p[name];
            if (a === b) {
                return typeof minor === 'function' ? minor(o, p) : 0;
            }
            if (typeof a === typeof b) {
                result = a < b ? -1 : 1;
            } else {
                result = typeof a < typeof b ? -1 : 1;
            }
            return result * reverseMutliplier;
        } else {
            throw {
                name: "Error",
                message: "Expected an object when sorting by " + name
            };
        }
    };
};

let s = [
    {first: 'Joe',   last: 'Besser'},
    {first: 'Moe',   last: 'Howard'},
    {first: 'Joe',   last: 'DeRita'},
    {first: 'Shemp', last: 'Howard'},
    {first: 'Larry', last: 'Fine'},
    {first: 'Curly', last: 'Howard'}
];

// Sort by: first ascending, last ascending
s.sort(by("first", by("last")));    
console.log("Sort by: first ascending, last ascending: ", s);     // "[
//     {"first":"Curly","last":"Howard"},
//     {"first":"Joe","last":"Besser"},     <======
//     {"first":"Joe","last":"DeRita"},     <======
//     {"first":"Larry","last":"Fine"},
//     {"first":"Moe","last":"Howard"},
//     {"first":"Shemp","last":"Howard"}
// ]

// Sort by: first ascending, last descending
s.sort(by("first", by("last", 0, false)));  
console.log("sort by: first ascending, last descending: ", s);    // "[
//     {"first":"Curly","last":"Howard"},
//     {"first":"Joe","last":"DeRita"},     <========
//     {"first":"Joe","last":"Besser"},     <========
//     {"first":"Larry","last":"Fine"},
//     {"first":"Moe","last":"Howard"},
//     {"first":"Shemp","last":"Howard"}
// ]

mythicalcoder
fonte
podemos classificar o {"first":"Curly","last":"Howard", "property" : {"id" : "1"}}tipo de matriz por id?
Sahu V Kumar
sim, a função precisa ser ligeiramente modificada para receber um novo parâmetro, por exemplo, nestedName. Você, então, chamar bycom name = "propriedade", nestedName = "id"
mythicalcoder
2

Apenas para uma matriz normal de valores de elementos:

function sortArrayOfElements(arrayToSort) {
    function compareElements(a, b) {
        if (a < b)
            return -1;
        if (a > b)
            return 1;
        return 0;
    }

    return arrayToSort.sort(compareElements);
}

e.g. 1:
var array1 = [1,2,545,676,64,2,24]
output : [1, 2, 2, 24, 64, 545, 676]

var array2 = ["v","a",545,676,64,2,"24"]
output: ["a", "v", 2, "24", 64, 545, 676]

Para uma matriz de objetos:

function sortArrayOfObjects(arrayToSort, key) {
    function compareObjects(a, b) {
        if (a[key] < b[key])
            return -1;
        if (a[key] > b[key])
            return 1;
        return 0;
    }

    return arrayToSort.sort(compareObjects);
}

e.g. 1: var array1= [{"name": "User4", "value": 4},{"name": "User3", "value": 3},{"name": "User2", "value": 2}]

output : [{"name": "User2", "value": 2},{"name": "User3", "value": 3},{"name": "User4", "value": 4}]
Umesh
fonte
2

Crie uma função e classifique com base na entrada usando o código abaixo

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": "5",
    "city": "New York",
    "state": "NY",
    "zip": "00010",
    "price": "962500"

 }];

 function sortList(list,order){
     if(order=="ASC"){
        return list.sort((a,b)=>{
            return parseFloat(a.price) - parseFloat(b.price);
        })
     }
     else{
        return list.sort((a,b)=>{
            return parseFloat(b.price) - parseFloat(a.price);
        });
     }
 }

 sortList(homes,'DESC');
 console.log(homes);
Andrew Rayan
fonte
2

Você pode usar string1.localeCompare (string2) para comparação de strings

this.myArray.sort((a,b) => { 
    return a.stringProp.localeCompare(b.stringProp);
});

Note-se que localCompareé caso em sensível

bradvido
fonte
1

Para classificação em vários campos de objetos de matriz. Digite o nome do seu campo na arrpropmatriz como ["a","b","c"] depois passe o segundo parâmetro arrsourceda fonte real que queremos classificar.

function SortArrayobject(arrprop,arrsource){
arrprop.forEach(function(i){
arrsource.sort(function(a,b){
return ((a[i] < b[i]) ? -1 : ((a[i] > b[i]) ? 1 : 0));
});
});
return arrsource;
}
Pradip Talaviya
fonte
1

Você precisará de duas funções

function desc(a, b) {
 return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
}

function asc(a, b) {
  return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}

Em seguida, você pode aplicar isso a qualquer propriedade do objeto:

 data.sort((a, b) => desc(parseFloat(a.price), parseFloat(b.price)));

let data = [
    {label: "one", value:10},
    {label: "two", value:5},
    {label: "three", value:1},
];

// sort functions
function desc(a, b) {
 return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
}

function asc(a, b) {
 return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}

// DESC
data.sort((a, b) => desc(a.value, b.value));

document.body.insertAdjacentHTML(
 'beforeend', 
 '<strong>DESCending sorted</strong><pre>' + JSON.stringify(data) +'</pre>'
);

// ASC
data.sort((a, b) => asc(a.value, b.value));

document.body.insertAdjacentHTML(
 'beforeend', 
 '<strong>ASCending sorted</strong><pre>' + JSON.stringify(data) +'</pre>'
);

OzzyCzech
fonte
0

Recentemente, escrevi uma função universal para gerenciar isso para você, se você quiser usá-lo.

/**
 * Sorts an object into an order
 *
 * @require jQuery
 *
 * @param object Our JSON object to sort
 * @param type Only alphabetical at the moment
 * @param identifier The array or object key to sort by
 * @param order Ascending or Descending
 *
 * @returns Array
 */
function sortItems(object, type, identifier, order){

    var returnedArray = [];
    var emptiesArray = []; // An array for all of our empty cans

    // Convert the given object to an array
    $.each(object, function(key, object){

        // Store all of our empty cans in their own array
        // Store all other objects in our returned array
        object[identifier] == null ? emptiesArray.push(object) : returnedArray.push(object);

    });

    // Sort the array based on the type given
    switch(type){

        case 'alphabetical':

            returnedArray.sort(function(a, b){

                return(a[identifier] == b[identifier]) ? 0 : (

                    // Sort ascending or descending based on order given
                    order == 'asc' ? a[identifier] > b[identifier] : a[identifier] < b[identifier]

                ) ? 1 : -1;

            });

            break;

        default:

    }

    // Return our sorted array along with the empties at the bottom depending on sort order
    return order == 'asc' ? returnedArray.concat(emptiesArray) : emptiesArray.concat(returnedArray);

}
Brad Bird
fonte
0
homes.sort(function(a, b){
  var nameA=a.prices.toLowerCase(), nameB=b.prices.toLowerCase()
  if (nameA < nameB) //sort string ascending
    return -1 
  if (nameA > nameB)
    return 1
  return 0 //default return value (no sorting)
})
user3346960
fonte
0

Olá, depois de ler este artigo, criei um sortComparator para minhas necessidades, com a funcionalidade de comparar mais de um atributo json, e quero compartilhá-lo com você.

Esta solução compara apenas seqüências de caracteres em ordem crescente, mas a solução pode ser facilmente estendida para cada atributo para oferecer suporte: ordem inversa, outros tipos de dados, uso de localidade, transmissão etc.

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": "5",
    "city": "New York",
    "state": "NY",
    "zip": "00010",
    "price": "962500"

}];

// comp = array of attributes to sort
// comp = ['attr1', 'attr2', 'attr3', ...]
function sortComparator(a, b, comp) {
    // Compare the values of the first attribute
    if (a[comp[0]] === b[comp[0]]) {
        // if EQ proceed with the next attributes
        if (comp.length > 1) {
            return sortComparator(a, b, comp.slice(1));
        } else {
            // if no more attributes then return EQ
            return 0;
        }
    } else {
        // return less or great
        return (a[comp[0]] < b[comp[0]] ? -1 : 1)
    }
}

// Sort array homes
homes.sort(function(a, b) {
    return sortComparator(a, b, ['state', 'city', 'zip']);
});

// display the array
homes.forEach(function(home) {
    console.log(home.h_id, home.city, home.state, home.zip, home.price);
});

e o resultado é

$ node sort
4 Bevery Hills CA 90210 319250
5 New York NY 00010 962500
3 Dallas TX 75201 162500

e outro tipo

homes.sort(function(a, b) {
    return sortComparator(a, b, ['city', 'zip']);
});

com resultado

$ node sort
4 Bevery Hills CA 90210 319250
3 Dallas TX 75201 162500
5 New York NY 00010 962500
George Vrynios
fonte
0

Um código simples:

    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": "5",
            "city": "New York",
            "state": "NY",
            "zip": "00010",
            "price": "962500"
        }
    ];

    let sortByPrice = homes.sort(function (a, b) 
    {
      return parseFloat(b.price) - parseFloat(a.price);
    });

    for (var i=0; i<sortByPrice.length; i++)
    {
      document.write(sortByPrice[i].h_id+' '+sortByPrice[i].city+' '
       +sortByPrice[i].state+' '
       +sortByPrice[i].zip+' '+sortByPrice[i].price);
      document.write("<br>");
    }

precipitadas
fonte
0
 function compareValues(key, order = 'asc') {
  return function innerSort(a, b) {
    if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
      // property doesn't exist on either object
      return 0;
    }

    const varA = (typeof a[key] === 'string')
      ? a[key].toUpperCase() : a[key];
    const varB = (typeof b[key] === 'string')
      ? b[key].toUpperCase() : b[key];

    let comparison = 0;
    if (varA > varB) {
      comparison = 1;
    } else if (varA < varB) {
      comparison = -1;
    }
    return (
      (order === 'desc') ? (comparison * -1) : comparison
    );
  };
}

http://yazilimsozluk.com/sort-array-in-javascript-by-asc-or-desc

user1688401
fonte