Sortieren eines Arrays von Objekten nach Eigenschaftswerten

1334

Ich habe die folgenden Objekte mit AJAX und habe sie in einem Array gespeichert:

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

Wie erstelle ich eine Funktion, um die Objekte nach der priceEigenschaft in aufsteigender oder absteigender Reihenfolge nur mit JavaScript zu sortieren ?

TomHankers
quelle
Am schnellsten ist es, das isomorphe Sort-Array- Modul zu verwenden, das sowohl im Browser als auch im Knoten nativ funktioniert und jede Art von Eingabe, berechneten Feldern und benutzerdefinierten Sortierreihenfolgen unterstützt.
Lloyd

Antworten:

1674

Sortieren Sie die Häuser nach Preis in aufsteigender Reihenfolge:

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

Oder nach der ES6-Version:

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

Einige Dokumentationen finden Sie hier .

Stobor
quelle
184
Sie können string1.localeCompare(string2)für String-Vergleich verwenden
Bradvido
62
Beachten Sie, dass localeCompare()die Groß- und Kleinschreibung nicht berücksichtigt wird . Wenn Sie zwischen Groß- und Kleinschreibung unterscheiden möchten, können Sie verwenden (string1 > string2) - (string1 < string2). Die Booleschen Werte werden zur Berechnung der Differenz auf die Ganzzahlen 0 und 1 gezwungen.
Don Kirkby
2
Vielen Dank für das Update, @Pointy. Ich erinnere mich nicht, dass ich auf dieses Problem gestoßen bin, aber vielleicht hat sich das Verhalten in den letzten Jahren geändert. Unabhängig davon zeigt die localeCompare()Dokumentation , dass Sie explizit angeben können, ob Sie Groß- und Kleinschreibung, numerische Sortierung und andere Optionen wünschen.
Don Kirkby
2
@ sg28 Ich denke, Sie haben die MDN-Erklärung falsch verstanden. Es heißt nicht, dass die Sortierfunktion nicht zuverlässig ist , sondern dass sie nicht stabil ist . Ich verstehe, warum dies verwirrend sein kann, aber das ist keine Behauptung, dass es nicht für die Verwendung geeignet ist. Im Zusammenhang mit Sortieralgorithmen hat der Begriff stabil eine bestimmte Bedeutung - dass "gleiche" Elemente in der Liste in derselben Reihenfolge wie in der Eingabe sortiert werden . Dies hat nichts mit der Idee von Code zu tun, der instabil ist (dh noch nicht einsatzbereit ist).
Stobor
1
Wenn Sie nach bestimmten Zeichenfolgenwerten sortieren möchten, beispielsweise nach Stadt, können Sie Folgendes
Jorge Valvert
675

Hier ist eine flexiblere Version, mit der Sie wiederverwendbare Sortierfunktionen erstellen und nach beliebigen Feldern sortieren können.

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

Triptychon
quelle
7
nickb - du liest den Code falsch. sort_bywird in O (1) ausgeführt und gibt eine Funktion zurück, die von der integrierten Sortierung (O (N log N)) zum Vergleichen von Elementen in einer Liste verwendet wird. Die Gesamtkomplexität ist O (n log n) * O (1), was sich auf O (n log n) reduziert, oder dasselbe wie eine schnelle Sortierung.
Triptychon
1
Ein Problem, das ich damit habe, ist, dass mit reverse = false Zahlen als 1,2,3,4 sortiert werden ... aber Strings als z, y, x ...
Abby
4
Eine kleine Verbesserung:var key = primer ? function (x) { return primer(x[field]); } : function (x) { return x[field]; }
ErikE
6
Während [1,-1][+!!reverse]Blicke abkühlen, dann ist es eine schreckliche Sache zu tun. Wenn ein Benutzer Ihre Methode nicht richtig aufrufen kann, bestrafen Sie ihn und versuchen Sie nicht, sie irgendwie zu verstehen, egal was passiert.
Ingo Bürk
2
Wäre es nicht besser, die Quelldaten vorzubereiten, würde dies zu einer fortlaufenden Analyse führen, wenn die Quelldaten eindeutig angepasst werden müssen.
Gerrit Brink
134

Um es zu sortieren, müssen Sie eine Komparatorfunktion mit zwei Argumenten erstellen. Rufen Sie dann die Sortierfunktion mit dieser Komparatorfunktion wie folgt auf:

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

Wenn Sie aufsteigend sortieren möchten, wechseln Sie die Ausdrücke auf jeder Seite des Minuszeichens.

Ricardo Marimon
quelle
3
Und hier ist eine Referenz, die das Thema tatsächlich erklärt, anstatt zu sagen: "Es ist zu kompliziert, Sie werden es sowieso nicht verstehen": developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Roland Illig
51

für die Sortierung von Zeichenfolgen, falls jemand sie benötigt,

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
quelle
38

Wenn Sie einen ES6- kompatiblen Browser haben, können Sie Folgendes verwenden:

Der Unterschied zwischen aufsteigender und absteigender Sortierreihenfolge ist das Vorzeichen des von Ihrer Vergleichsfunktion zurückgegebenen Werts:

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

Hier ist ein Arbeitscode-Snippet:

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
quelle
22

Du willst es in Javascript sortieren, oder? Was Sie wollen, ist die sort()Funktion . In diesem Fall müssen Sie eine Komparatorfunktion schreiben und an übergeben sort(), also ungefähr so:

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

Ihr Komparator verwendet jeweils einen der verschachtelten Hashes im Array und entscheidet anhand des Felds "Preis", welcher höher ist.

Tim Gilbert
quelle
21

Ich empfehle GitHub: Array sortBy - eine beste Implementierung einer sortByMethode, die die Schwartzsche Transformation verwendet

Aber jetzt werden wir diesen Ansatz versuchen. Gist: sortBy-old.js .
Erstellen wir eine Methode zum Sortieren von Arrays, mit denen Objekte nach einer Eigenschaft angeordnet werden können.

Sortierfunktion erstellen

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

}());

Unsortierte Daten einstellen

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

Es benutzen

Ordnen Sie das Array nach "date"as anString

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

Wenn Sie die Groß- und Kleinschreibung ignorieren möchten, legen Sie den parserRückruf fest:

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

Wenn Sie das "date"Feld als DateTyp konvertieren möchten :

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

Hier können Sie mit dem Code spielen: jsbin.com/lesebi

Dank @Ozesh durch sein Feedback wurde das Problem im Zusammenhang mit Eigenschaften mit falschen Werten behoben.

Jherax
quelle
Dies scheint zu brechen, wenn ein Feld null ist.
TSNev
Wenn Sie Zahlen sortieren und zwischen dem Array von Objekten eine '0' feststellen, stellen Sie möglicherweise fest, dass der obige Code nicht var checkNaN = function (value) { return Number.isNaN(Number(value)) ? 0 : value; } funktioniert . Hier ist eine schnelle Lösung dafür: gefolgt von: 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

Verwenden Sie lodash.sortBy (Anweisungen mit commonjs, Sie können auch einfach das Skript-Include-Tag für die CDN oben in Ihr HTML einfügen)

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

Absteigende Reihenfolge

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

Aufsteigende Reihenfolge

var ascendingOrder = sortBy( homes, 'price' );
Evan Carroll
quelle
1
Oderconst sortBy = require('lodash/sortBy'); let calendars = sortBy(calendarListResponse.items, cal => cal.summary);
mpen
Ich bin mir nicht sicher, ob Loadash kürzlich seinen Namen OrderBy geändert hatimport { orderBy } from 'lodash'; ... ... return orderBy ( rows, 'fieldName' ).reverse();
montelof
8

Dies hätte durch eine einfache Sortierfunktion mit einem Zeilenwert von () erreicht werden können. Führen Sie das folgende Code-Snippet aus, um die Demo zu sehen.

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
quelle
8

Ich bin etwas spät dran für die Party, aber unten ist meine Logik zum Sortieren.

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

Obwohl mir bekannt ist, dass das OP eine Reihe von Zahlen sortieren wollte, wurde diese Frage als Antwort auf ähnliche Fragen zu Zeichenfolgen markiert. In diesem Zusammenhang wird in den obigen Antworten nicht berücksichtigt, ob ein Textarray sortiert werden soll, bei dem die Groß- und Kleinschreibung wichtig ist. Die meisten Antworten nehmen die Zeichenfolgenwerte und konvertieren sie in Groß- / Kleinbuchstaben und sortieren sie dann auf die eine oder andere Weise. Die Anforderungen, an die ich mich halte, sind einfach:

  • Alphabetisch sortieren AZ
  • Großbuchstaben desselben Wortes sollten vor Kleinbuchstaben stehen
  • Gleiche Buchstabenwerte (A / a, B / b) sollten zusammengefasst werden

Was ich erwarte, ist [ A, a, B, b, C, c ], dass die obigen Antworten zurückkehren A, B, C, a, b, c. Ich habe mich tatsächlich länger am Kopf gekratzt, als ich wollte (weshalb ich dies in der Hoffnung poste, dass es mindestens einer anderen Person helfen wird). Während zwei Benutzer die localeCompareFunktion in den Kommentaren für die markierte Antwort erwähnen , habe ich das erst gesehen, nachdem ich beim Durchsuchen auf die Funktion gestoßen bin. Nachdem ich die Dokumentation zu String.prototype.localeCompare () gelesen hatte, konnte ich Folgendes finden :

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

Dies weist die Funktion an, Großbuchstaben vor Kleinbuchstaben zu sortieren. Der zweite Parameter in der localeCompareFunktion besteht darin, das Gebietsschema zu definieren. Wenn Sie es jedoch verlassen undefined, wird das Gebietsschema automatisch für Sie ermittelt.

Dies funktioniert auch beim Sortieren eines Arrays von Objekten:

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
quelle
5

Sie können die JavaScript- sortMethode mit einer Rückruffunktion verwenden:

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.
quelle
4

Hier ist ein Höhepunkt aller obigen Antworten.

Geigenvalidierung: 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();

        }));
    }


}
Bob
quelle
Können Sie bitte erklären, welche Bedeutung es hat, * zu haben (rev? -1: 1)?
TechTurtle
Das heißt, um die Reihenfolge umzukehren (aufsteigend oder absteigend), dreht der Rev-Teil nur normale Ergebnisse, wenn das Rev-Argument wahr ist. Andernfalls wird es nur mit 1 multipliziert, was nichts bewirkt. Wenn es gesetzt ist, wird das Ergebnis mit -1 multipliziert, wodurch das Ergebnis invertiert wird.
Bob
3

Zum Sortieren eines Arrays müssen Sie eine Komparatorfunktion definieren. Diese Funktion unterscheidet sich immer von Ihrem gewünschten Sortiermuster oder Ihrer gewünschten Reihenfolge (dh aufsteigend oder absteigend).

Erstellen Sie einige Funktionen, die ein Array aufsteigend oder absteigend sortieren und Objekt-, Zeichenfolgen- oder numerische Werte enthalten.

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

Zahlen sortieren (alphabetisch und aufsteigend):

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

Zahlen sortieren (alphabetisch und absteigend):

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

Nummern sortieren (numerisch und aufsteigend):

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

Nummern sortieren (numerisch und absteigend):

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

Verwenden Sie wie oben beschrieben die Methoden sorterPriceAsc und sorterPriceDes für Ihr Array mit dem gewünschten Schlüssel.

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

Ich habe auch mit einer Art Bewertung und mehreren Feldern gearbeitet:

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

Ergebnis

[
    {"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
quelle
3

Diese Prototypfunktion ist zwar ein wenig übertrieben, wenn nur ein einzelnes Array sortiert wird, ermöglicht jedoch das Sortieren von Javascript-Arrays nach beliebigen Schlüsseln in aufsteigender oder absteigender Reihenfolge, einschließlich verschachtelter Schlüssel , mithilfe der dotSyntax.

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

Verwendungszweck:

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

Sortieren nach verschachtelten Eigenschaften mit Punktsyntax oder Array-Syntax:

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

Sortieren nach mehreren Schlüsseln:

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

Sie können das Repo teilen: https://github.com/eneko/Array.sortBy

Eneko Alonso
quelle
Ich mag diese Antwort sehr wegen der sortByprägnanten Syntax. Einfach zu verwenden - auch bei verschachtelten Feldern - bei gleichzeitig hervorragender Lesbarkeit des Codes. Vielen Dank!
Manfred Urban
3

Mit ECMAScript 6 kann die Antwort von StoBor noch präziser erfolgen:

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

Absteigende Reihenfolge des Preises:

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

Aufsteigende Preisreihenfolge:

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

Wenn Sie Underscore.js verwenden , versuchen Sie 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
quelle
2

Hier ist eine leicht modifizierte Version der eleganten Implementierung aus dem Buch "JavaScript: The Good Parts".

HINWEIS : Diese Version von byist stabil . Die Reihenfolge der ersten Sortierung bleibt erhalten, während die nächste verkettete Sortierung ausgeführt wird.

Ich habe isAscendingParameter hinzugefügt . Konvertierte es auch in ES6Standards und "neuere" gute Teile, wie vom Autor empfohlen.

Sie können sowohl aufsteigend als auch absteigend sortieren und die Kette nach mehreren Eigenschaften sortieren.

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

mythischer Kodierer
quelle
Können wir den {"first":"Curly","last":"Howard", "property" : {"id" : "1"}}Array-Typ nach ID sortieren ?
Sahu V Kumar
Ja, die Funktion muss leicht geändert werden, um einen neuen Parameter aufzunehmen, z. B. nestedName. Sie rufen dann bymit name = "property", nestedName = "id"
mythicalcoder
2

Nur für ein normales Array von Elementwerten:

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]

Für eine Reihe von Objekten:

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
quelle
2

Erstellen Sie eine Funktion und sortieren Sie sie basierend auf der Eingabe mit dem folgenden Code

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
quelle
2

Sie können string1.localeCompare (string2) für den Stringvergleich verwenden

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

Beachten Sie, dass localComparedies bei sensiblen Fällen der Fall ist

Bradvido
quelle
1

Zum Sortieren nach mehreren Array-Objektfeldern. Geben Sie Ihren Feldnamen in das arrpropArray ein ["a","b","c"] und übergeben Sie den zweiten Parameter der arrsourcetatsächlichen Quelle, die wir sortieren möchten.

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
quelle
1

Sie benötigen zwei Funktionen

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

Dann können Sie dies auf jede Objekteigenschaft anwenden:

 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
quelle
0

Ich habe kürzlich eine universelle Funktion geschrieben, um dies für Sie zu verwalten, wenn Sie es verwenden möchten.

/**
 * 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
quelle
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
quelle
0

Hallo, nachdem ich diesen Artikel gelesen habe, habe ich einen sortComparator für meine Bedürfnisse erstellt, mit der Funktionalität, mehr als ein json-Attribut zu vergleichen, und ich möchte ihn mit Ihnen teilen.

Diese Lösung vergleicht nur Zeichenfolgen in aufsteigender Reihenfolge, aber die Lösung kann für jedes Attribut einfach erweitert werden, um Folgendes zu unterstützen: umgekehrte Reihenfolge, andere Datentypen, Gebietsschema, Casting usw.

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

und das Ergebnis ist

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

und eine andere Art

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

mit Ergebnis

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

Ein einfacher Code:

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

Rashedcs
quelle
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
quelle