Ordinamento di una matrice di oggetti in base ai valori delle proprietà


1334

Ho i seguenti oggetti usando AJAX e li ho archiviati in un array:

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"
    }
];

Come faccio a creare una funzione per ordinare gli oggetti in base alla priceproprietà in ordine crescente o decrescente usando solo JavaScript?


il modo più rapido è utilizzare il modulo di ordinamento-array isomorfo che funziona nativamente sia nel browser che nel nodo, supportando qualsiasi tipo di input, campi calcolati e ordinamenti personalizzati.
Lloyd,

Risposte:


1674

Ordina le case per prezzo in ordine crescente:

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

O dopo la versione ES6:

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

Alcuni documenti sono disponibili qui .


184
È possibile utilizzare string1.localeCompare(string2)per il confronto delle stringhe
bradvido,

62
Tieni presente che non distingue tralocaleCompare() maiuscole e minuscole . Se si desidera la distinzione tra maiuscole e minuscole, è possibile utilizzare (string1 > string2) - (string1 < string2). I valori booleani sono costretti a numeri interi 0 e 1 per calcolare la differenza.
Don Kirkby,

2
Grazie per l'aggiornamento, @Pointy, non ricordo di essermi imbattuto in questo problema, ma forse il comportamento è cambiato negli ultimi due anni. Indipendentemente da ciò, la localeCompare()documentazione mostra che è possibile dichiarare esplicitamente se si desidera la distinzione tra maiuscole e minuscole, l'ordinamento numerico e altre opzioni.
Don Kirkby,

2
@ sg28 Penso che tu abbia frainteso la spiegazione MDN. Non dice che la funzione di ordinamento non è affidabile , dice che non è stabile . Capisco perché questo può essere fonte di confusione, ma non è un'affermazione che non è adatto per l'uso. Nel contesto degli algoritmi di ordinamento, il termine stabile ha un significato specifico: gli elementi "uguali" nell'elenco sono ordinati nello stesso ordine dell'input . Ciò è completamente estraneo all'idea di codice instabile (ovvero non ancora pronto per l'uso).
Stobor,

1
Se si desidera ordinare in base a valori stringa specifici, ad esempio per città, è possibile utilizzare: this.homes.sort ((current, next) => {return current.city.localeCompare (next.city)});
Jorge Valvert,

675

Ecco una versione più flessibile, che ti consente di creare funzioni di ordinamento riutilizzabili e ordinarle per qualsiasi 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()
)));


7
nickb: stai leggendo male il codice. sort_byviene eseguito in O (1) e restituisce una funzione utilizzata dall'ordinamento incorporato (O (N log N)) per confrontare gli elementi in un elenco. La complessità totale è O (n log n) * O (1) che si riduce a O (n log n), o lo stesso di un ordinamento rapido.
Trittico,

1
Un problema che ho con questo è che con reverse = false, ordinerà i numeri come 1,2,3,4 ... ma le stringhe come z, y, x ...
Abby,

4
Un piccolo miglioramento:var key = primer ? function (x) { return primer(x[field]); } : function (x) { return x[field]; }
ErikE

6
Anche se [1,-1][+!!reverse]sembra bello, è una cosa orribile da fare. Se un utente non può chiamare correttamente il tuo metodo, puniscilo, non provare a dargli un senso, non importa quale.
Ingo Bürk,

2
Non sarebbe meglio preparare i dati di origine, questo causerebbe un analisi consecutiva quando chiaramente i dati di origine hanno bisogno di qualche modifica.
Gerrit Brink,

134

Per ordinarlo è necessario creare una funzione di comparazione prendendo due argomenti. Quindi chiama la funzione di ordinamento con quella funzione di confronto come segue:

// 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 si desidera ordinare in ordine crescente, cambiare le espressioni su ciascun lato del segno meno.


3
Ed ecco un riferimento che in realtà spiega l'argomento invece di dire "è troppo complicato, non lo capirai comunque": developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Roland Illig,

51

per l'ordinamento delle stringhe nel caso in cui qualcuno ne abbia bisogno,

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;
}));


38

Se si dispone di un browser conforme a ES6 è possibile utilizzare:

La differenza tra l'ordinamento crescente e decrescente è il segno del valore restituito dalla funzione di confronto:

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

Ecco uno snippet di codice funzionante:

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);


22

Vuoi ordinarlo in Javascript, giusto? Quello che vuoi è la sort()funzione . In questo caso devi scrivere una funzione di confronto e passarla a sort(), quindi qualcosa del genere:

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));

Il tuo comparatore prende uno di ciascuno degli hash nidificati all'interno dell'array e decide quale è più alto controllando il campo "prezzo".


21

Raccomando GitHub: Array sortBy - una migliore implementazione del sortBymetodo che utilizza il trasformata di Schwartz

Ma per ora proveremo questo approccio Gist: sortBy-old.js .
Creiamo un metodo per ordinare le matrici potendo disporre gli oggetti in base a qualche proprietà.

Creazione della funzione di ordinamento

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));
    });
  };

}());

Impostazione di dati non ordinati

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"}
];

Usandolo

Disporre l'array, in base a "date"comeString

// 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 si desidera ignorare la distinzione tra maiuscole e minuscole, impostare la parserrichiamata:

// 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 vuoi convertire il "date"campo come 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" }

Qui puoi giocare con il codice: jsbin.com/lesebi

Grazie a @Ozesh dal suo feedback, il problema relativo alle proprietà con valori falsi è stato risolto.


Questo sembra interrompersi quando un campo è nullo.
TSNev,

Nel caso in cui stai ordinando i numeri e incontri uno '0' tra l'array di oggetti, potresti notare che il codice sopra riportato si rompe. Ecco una soluzione rapida per questo: var checkNaN = function (value) { return Number.isNaN(Number(value)) ? 0 : value; } seguito da: return function (array, o) { .... a = _getItem.call (o, a); a = checkNaN (a); b = _getItem.call (o, b); b = checkNaN (b); return o.desc * (a <b? -1: + (a> b)); });
Ozesh,

18

Usa lodash.sortBy , (istruzioni usando commonjs, puoi anche mettere lo script include-tag per il cdn nella parte superiore del tuo html)

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

Ordine decrescente

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

Ordine ascendente

var ascendingOrder = sortBy( homes, 'price' );

1
Oppureconst sortBy = require('lodash/sortBy'); let calendars = sortBy(calendarListResponse.items, cal => cal.summary);
mpen

non sono sicuro che loadash sia cambiato di recente ormai con il nome OrderByimport { orderBy } from 'lodash'; ... ... return orderBy ( rows, 'fieldName' ).reverse();
montelof

8

Ciò avrebbe potuto essere ottenuto attraverso una semplice funzione value sort () di una riga . Esegui lo snippet di codice qui sotto per vedere la demo.

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);


8

Sono in ritardo per la festa, ma di seguito è la mia logica per l'ordinamento.

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

6

Mentre sono consapevole che l'OP ha voluto ordinare una serie di numeri, questa domanda è stata contrassegnata come la risposta a domande simili riguardanti le stringhe. A tal proposito, le risposte di cui sopra non considerano l'ordinamento di una matrice di testo in cui il case è importante. La maggior parte delle risposte prende i valori di stringa e li converte in maiuscolo / minuscolo, quindi ordina in un modo o nell'altro. I requisiti a cui aderisco sono semplici:

  • Ordina in ordine alfabetico AZ
  • I valori maiuscoli della stessa parola devono precedere i valori minuscoli
  • I valori della stessa lettera (A / a, B / b) devono essere raggruppati insieme

Quello che mi aspetto è [ A, a, B, b, C, c ]che le risposte sopra riportate ritornino A, B, C, a, b, c. In realtà mi sono grattato la testa più a lungo di quanto volessi (motivo per cui sto pubblicando questo nella speranza che possa aiutare almeno un'altra persona). Mentre due utenti menzionano la localeComparefunzione nei commenti per la risposta contrassegnata, non l'ho visto fino a quando non mi sono imbattuto nella funzione durante la ricerca. Dopo aver letto la documentazione String.prototype.localeCompare () sono stato in grado di trovare questo:

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" ]

Questo dice alla funzione di ordinare i valori maiuscoli prima dei valori minuscoli. Il secondo parametro nella localeComparefunzione è definire la locale, ma se la lasci, in undefinedquanto individua automaticamente la locale per te.

Questo funziona allo stesso modo anche per ordinare un array di oggetti:

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" }));

5

È possibile utilizzare il sortmetodo JavaScript con una funzione di callback:

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);

4

Ecco il culmine di tutte le risposte sopra.

Convalida del violino: 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();

        }));
    }


}

puoi spiegare qual è il significato di avere * (rev? -1: 1);
TechTurtle,

Questo per invertire l'ordine (crescente o decrescente) la porzione rev fa semplicemente girare i risultati normali quando l'argomento rev è vero. Altrimenti si moltiplica per 1 che non fa nulla, quando impostato, moltiplica il risultato per -1, invertendo così il risultato.
bob

3

Per ordinare un array è necessario definire una funzione di confronto. Questa funzione è sempre diversa sul modello di ordinamento o sull'ordine desiderato (ovvero crescente o decrescente).

Permettiamo di creare alcune funzioni che ordinano un array crescente o decrescente e che contiene oggetti o stringhe o valori numerici.

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']);
}

Ordina i numeri (in ordine alfabetico e crescente):

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

Ordina i numeri (in ordine alfabetico e decrescente):

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

Ordina i numeri (numericamente e in ordine crescente):

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

Ordina i numeri (numericamente e in ordine decrescente):

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

Come sopra, usa i metodi sorterPriceAsc e sorterPriceDes con l'array con la chiave desiderata.

homes.sort(sorterPriceAsc()) or homes.sort(sorterPriceDes())

3

Ho anche lavorato con una sorta di valutazione e ordinamento di più campi:

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);
});

Risultato

[
    {"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}
]

3

Sebbene sia un po 'eccessivo per l'ordinamento di un singolo array, questa funzione prototipo consente di ordinare gli array Javascript con qualsiasi chiave, in ordine crescente o decrescente, comprese le chiavi nidificate , utilizzando la dotsintassi.

(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)"

Ordinamento per proprietà nidificate con sintassi punto o sintassi array:

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)"

Ordinamento per più chiavi:

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)"

È possibile fork il repository: https://github.com/eneko/Array.sortBy


Mi piace molto questa risposta a causa della sortBysintassi concisa. Semplice da usare, anche con campi nidificati, pur mantenendo un'ottima leggibilità del codice. Grazie!
Manfred Urban,

3

Con ECMAScript 6 la risposta di StoBor può essere fatta ancora più concisa:

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

3

Ordine discendente del prezzo:

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

Ordine crescente di prezzo:

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

2

Se usi Underscore.js , prova sortBy:

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

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

2

Ecco una versione leggermente modificata di elegante implementazione dal libro "JavaScript: The Good Parts".

NOTA : questa versione di byè stabile . Conserva l'ordine del primo ordinamento durante l'esecuzione del successivo ordinamento concatenato.

Ho aggiunto un isAscendingparametro ad esso. Lo ha anche convertito in ES6standard e parti più "nuove" come raccomandato dall'autore.

È possibile ordinare in ordine crescente o decrescente e ordinamento a catena in base a più proprietà.

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"}
// ]


potremmo ordinare il {"first":"Curly","last":"Howard", "property" : {"id" : "1"}}tipo di array per ID?
Sahu V Kumar,

Sì, la funzione deve essere leggermente modificata per includere un nuovo parametro, ad esempio, nestedName. Quindi chiami bycon name = "property", nestedName = "id"
mythicalcoder il

2

Solo per una normale matrice di valori di elementi:

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]

Per una matrice di oggetti:

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}]

2

Crea una funzione e ordina in base all'input usando il codice seguente

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);

2

È possibile utilizzare string1.localeCompare (string2) per il confronto delle stringhe

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

Si noti che localCompareè sensibile al maiuscolo / minuscolo


1

Per l'ordinamento su più campi oggetto array. Inserisci il nome del campo arrpropnell'array come, ["a","b","c"] quindi passa arrsourcela fonte effettiva del secondo parametro che vogliamo ordinare.

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;
}

1

Avrai bisogno di due funzioni

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;
}

Quindi puoi applicarlo a qualsiasi proprietà dell'oggetto:

 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>'
);


0

Di recente ho scritto una funzione universale per gestirla se vuoi usarla.

/**
 * 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);

}

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)
})

0

Ciao dopo aver letto questo articolo, ho creato un sortComparator per le mie esigenze, con la funzionalità per confrontare più di un attributo json e voglio condividerlo con te.

Questa soluzione confronta solo le stringhe in ordine crescente, ma la soluzione può essere facilmente estesa per ogni attributo da supportare: ordine inverso, altri tipi di dati, per usare le impostazioni locali, il cast ecc.

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 il risultato è

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

e un altro tipo

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

con risultato

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

0

Un semplice codice:

    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>");
    }


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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.