it-swarm.com.de

Sortieren Sie das Array von Objekten nach dem Wert der Zeichenfolgeeigenschaft

Ich habe eine Reihe von JavaScript-Objekten:

var objs = [ 
    { first_nom: 'Lazslo', last_nom: 'Jamf'     },
    { first_nom: 'Pig',    last_nom: 'Bodine'   },
    { first_nom: 'Pirate', last_nom: 'Prentice' }
];

Wie kann ich sie nach dem Wert von last_nom in JavaScript sortieren?

Ich kenne sort(a,b), aber das scheint nur mit Zeichenfolgen und Zahlen zu funktionieren. Muss ich meinen Objekten eine toString() -Methode hinzufügen?

2408
Tyrone Slothrop

Es ist einfach genug, eine eigene Vergleichsfunktion zu schreiben:

function compare( a, b ) {
  if ( a.last_nom < b.last_nom ){
    return -1;
  }
  if ( a.last_nom > b.last_nom ){
    return 1;
  }
  return 0;
}

objs.sort( compare );

Oder inline (c/o Marco Demaio):

objs.sort((a,b) => (a.last_nom > b.last_nom) ? 1 : ((b.last_nom > a.last_nom) ? -1 : 0)); 
3472
Wogan

Sie können auch eine dynamische Sortierfunktion erstellen, die Objekte nach ihrem übergebenen Wert sortiert:

function dynamicSort(property) {
    var sortOrder = 1;
    if(property[0] === "-") {
        sortOrder = -1;
        property = property.substr(1);
    }
    return function (a,b) {
        /* next line works with strings and numbers, 
         * and you may want to customize it to your needs
         */
        var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
        return result * sortOrder;
    }
}

So können Sie eine Reihe von Objekten wie folgt haben:

var People = [
    {Name: "Name", Surname: "Surname"},
    {Name:"AAA", Surname:"ZZZ"},
    {Name: "Name", Surname: "AAA"}
];

... und es wird funktionieren, wenn Sie:

People.sort(dynamicSort("Name"));
People.sort(dynamicSort("Surname"));
People.sort(dynamicSort("-Surname"));

Eigentlich beantwortet dies bereits die Frage. Der folgende Teil ist geschrieben, weil viele Leute mich kontaktiert haben und sich beschwert haben, dass es funktioniert nicht mit mehreren Parametern .

Mehrere Parameter

Mit der folgenden Funktion können Sie Sortierfunktionen mit mehreren Sortierparametern generieren.

function dynamicSortMultiple() {
    /*
     * save the arguments object as it will be overwritten
     * note that arguments object is an array-like object
     * consisting of the names of the properties to sort by
     */
    var props = arguments;
    return function (obj1, obj2) {
        var i = 0, result = 0, numberOfProperties = props.length;
        /* try getting a different result from 0 (equal)
         * as long as we have extra properties to compare
         */
        while(result === 0 && i < numberOfProperties) {
            result = dynamicSort(props[i])(obj1, obj2);
            i++;
        }
        return result;
    }
}

Was würde es Ihnen ermöglichen, so etwas zu tun:

People.sort(dynamicSortMultiple("Name", "-Surname"));

Unterklassen-Array

Für die glücklichen unter uns, die ES6 verwenden können, mit dem die nativen Objekte erweitert werden können:

class MyArray extends Array {
    sortBy(...args) {
        return this.sort(dynamicSortMultiple.apply(null, args));
    }
}

Das würde folgendes ermöglichen:

MyArray.from(People).sortBy("Name", "-Surname");
776
Ege Özcan

In ES6/ES2015 oder höher können Sie folgendermaßen vorgehen:

objs.sort((a, b) => a.last_nom.localeCompare(b.last_nom));
302
Vlad Bezden

nderscore.js

verwenden Sie Unterstrich, es ist klein und genial ...

sortBy_.sortBy (list, iterator, [context]) Gibt eine sortierte Kopie der Liste zurück, die in aufsteigender Reihenfolge nach den Ergebnissen der Ausführung der einzelnen Werte durch den Iterator geordnet ist. Iterator kann auch der Zeichenfolgenname der Eigenschaft sein, nach der sortiert werden soll (z. B. Länge).

var objs = [ 
  { first_nom: 'Lazslo',last_nom: 'Jamf' },
  { first_nom: 'Pig', last_nom: 'Bodine'  },
  { first_nom: 'Pirate', last_nom: 'Prentice' }
];

var sortedObjs = _.sortBy( objs, 'first_nom' );
178
David Morrow

Verstehe nicht, warum die Leute es so kompliziert machen:

objs.sort(function(a, b){
  return a.last_nom > b.last_nom;
});

Für strengere Motoren:

objs.sort(function(a, b){
  return a.last_nom == b.last_nom ? 0 : +(a.last_nom > b.last_nom) || -1;
});

Tauschen Sie den Operator aus, damit er in umgekehrter alphabetischer Reihenfolge sortiert wird.

169
p3lim

Wenn Sie doppelte Nachnamen haben, können Sie diese nach Vornamen sortieren.

obj.sort(function(a,b){
  if(a.last_nom< b.last_nom) return -1;
  if(a.last_nom >b.last_nom) return 1;
  if(a.first_nom< b.first_nom) return -1;
  if(a.first_nom >b.first_nom) return 1;
  return 0;
});
61
kennebec

Einfache und schnelle Lösung dieses Problems mithilfe der Vererbung von Prototypen:

Array.prototype.sortBy = function(p) {
  return this.slice(0).sort(function(a,b) {
    return (a[p] > b[p]) ? 1 : (a[p] < b[p]) ? -1 : 0;
  });
}

Beispiel/Verwendung

objs = [{age:44,name:'vinay'},{age:24,name:'deepak'},{age:74,name:'suresh'}];

objs.sortBy('age');
// Returns
// [{"age":24,"name":"deepak"},{"age":44,"name":"vinay"},{"age":74,"name":"suresh"}]

objs.sortBy('name');
// Returns
// [{"age":24,"name":"deepak"},{"age":74,"name":"suresh"},{"age":44,"name":"vinay"}]

pdate: Ändert das ursprüngliche Array nicht mehr.

42
Vinay Aggarwal

Ab 2018 gibt es eine viel kürzere und elegantere Lösung. Benutz einfach. Array.prototype.sort () .

Beispiel:

var items = [
  { name: 'Edward', value: 21 },
  { name: 'Sharpe', value: 37 },
  { name: 'And', value: 45 },
  { name: 'The', value: -12 },
  { name: 'Magnetic', value: 13 },
  { name: 'Zeros', value: 37 }
];

// sort by value
items.sort(function (a, b) {
  return a.value - b.value;
});
31
0leg

Anstatt eine benutzerdefinierte Vergleichsfunktion zu verwenden, können Sie auch einen Objekttyp mit der benutzerdefinierten Methode toString() erstellen (die von der Standardvergleichsfunktion aufgerufen wird):

function Person(firstName, lastName) {
    this.firtName = firstName;
    this.lastName = lastName;
}

Person.prototype.toString = function() {
    return this.lastName + ', ' + this.firstName;
}

var persons = [ new Person('Lazslo', 'Jamf'), ...]
persons.sort();
28
Christoph

Sie können verwenden

Einfachster Weg: Lodash

( https://lodash.com/docs/4.17.10#orderBy )

Diese Methode ähnelt _.sortBy mit der Ausnahme, dass die Sortierreihenfolge der zu sortierenden Iteratees angegeben werden kann. Wenn die Reihenfolge nicht angegeben ist, werden alle Werte in aufsteigender Reihenfolge sortiert. Andernfalls geben Sie eine Reihenfolge von "desc" für den Abstieg oder "asc" für die aufsteigende Sortierreihenfolge der entsprechenden Werte an.

Argumente

collection (Array | Object): Die Sammlung, über die iteriert werden soll. [iteratees = [_. identity]] (Array [] | Function [] | Object [] | string []): Die zu sortierenden Iterationen. [orders] (string []): Die Sortierreihenfolge der Wiederholungen.

Rückgabe

(Array): Gibt das neu sortierte Array zurück.


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

_.orderBy(homes, ['city', 'state', 'Zip'], ['asc', 'desc', 'asc']);
26
Harshal

Lodash.js (Obermenge von nderscore.js )

Es ist gut, nicht für jede einfache Logik ein Framework hinzuzufügen, aber sich auf ein gut getestetes Utility-Framework zu verlassen, die Entwicklung zu beschleunigen und die Anzahl der geschriebenen Fehler zu reduzieren, ist keine Schande.

Lodash produziert sehr sauberen Code und fördert einen funktionaleren Programmierstil , der zu weniger Fehlern führt. Auf einen Blick wird klar, was die Absicht ist, wenn der Code ist.

OP's Problem kann einfach gelöst werden als:

const sortedObjs = _.sortBy(objs, 'last_nom');

Mehr Info? Z.B. Wir haben folgendes verschachteltes Objekt:

const users = [
  { 'user': {'name':'fred', 'age': 48}},
  { 'user': {'name':'barney', 'age': 36 }},
  { 'user': {'name':'wilma'}},
  { 'user': {'name':'betty', 'age': 32}}
];

Wir können jetzt die _. Eigenschaft Kurzform user.age verwenden, um den Pfad zu der Eigenschaft anzugeben, die abgeglichen werden soll. Wir sortieren die Benutzerobjekte nach der Eigenschaft "verschachteltes Alter". Ja, es ermöglicht den Abgleich von verschachtelten Eigenschaften!

const sortedObjs = _.sortBy(users, ['user.age']);

Willst du es umgekehrt? Kein Problem. Verwenden Sie _. Reverse .

const sortedObjs = _.reverse(_.sortBy(users, ['user.age']));

Möchten Sie beides mit Verkettung kombinieren?

const sortedObjs = _.chain(users).sortBy('user.age').reverse().value();
22
Nico Van Belle

Hier gibt es viele gute Antworten, aber ich möchte darauf hinweisen, dass sie sehr einfach erweitert werden können, um eine viel komplexere Sortierung zu erreichen. Das Einzige, was Sie tun müssen, ist, den Operator OR zu verwenden, um Vergleichsfunktionen wie diese zu verketten:

objs.sort((a,b)=> fn1(a,b) || fn2(a,b) || fn3(a,b) )

Wobei fn1, fn2, ... die Sortierfunktionen sind, die [-1,0,1] zurückgeben. Dies führt zu "Sortierung nach fn1" und "Sortierung nach fn2", was in SQL ziemlich gleich ORDER BY ist.

Diese Lösung basiert auf dem Verhalten des Operators ||, der den zuerst ausgewerteten Ausdruck ergibt, der in true konvertiert werden kann.

Die einfachste Form hat nur eine inline Funktion wie diese:

// ORDER BY last_nom
objs.sort((a,b)=> a.last_nom.localeCompare(b.last_nom) )

Wenn Sie zwei Schritte mit last_nom, first_nom ausführen, sieht die Sortierreihenfolge folgendermaßen aus:

// ORDER_BY last_nom, first_nom
objs.sort((a,b)=> a.last_nom.localeCompare(b.last_nom) || 
                  a.first_nom.localeCompare(b.first_nom)  )

Eine generische Vergleichsfunktion könnte ungefähr so ​​aussehen:

// ORDER BY <n>
let cmp = (a,b,n)=>a[n].localeCompare(b[n])

Diese Funktion kann erweitert werden, um numerische Felder, Groß- und Kleinschreibung, beliebige Datentypen usw. zu unterstützen.

Sie können sie verwenden, indem Sie sie nach Sortierpriorität verketten:

// ORDER_BY last_nom, first_nom
objs.sort((a,b)=> cmp(a,b, "last_nom") || cmp(a,b, "first_nom") )
// ORDER_BY last_nom, first_nom DESC
objs.sort((a,b)=> cmp(a,b, "last_nom") || -cmp(a,b, "first_nom") )
// ORDER_BY last_nom DESC, first_nom DESC
objs.sort((a,b)=> -cmp(a,b, "last_nom") || -cmp(a,b, "first_nom") )

Der Punkt hier ist, dass reines JavaScript mit funktionalem Ansatz Sie weit ohne externe Bibliotheken oder komplexen Code bringen kann. Es ist auch sehr effektiv, da kein String-Parsing durchgeführt werden muss

22
Tero Tolonen

Beispiel Verwendung:

objs.sort(sortBy('last_nom'));

Skript:

/**
 * @description
 * Returns a function which will sort an
 * array of objects by the given key.
 *
 * @param  {String}  key
 * @param  {Boolean} reverse
 * @return {Function}
 */
const sortBy = (key, reverse) => {

  // Move smaller items towards the front
  // or back of the array depending on if
  // we want to sort the array in reverse
  // order or not.
  const moveSmaller = reverse ? 1 : -1;

  // Move larger items towards the front
  // or back of the array depending on if
  // we want to sort the array in reverse
  // order or not.
  const moveLarger = reverse ? -1 : 1;

  /**
   * @param  {*} a
   * @param  {*} b
   * @return {Number}
   */
  return (a, b) => {
    if (a[key] < b[key]) {
      return moveSmaller;
    }
    if (a[key] > b[key]) {
      return moveLarger;
    }
    return 0;
  };
};
20
Jamie Mason

Ich habe einen Code, der für mich funktioniert:

arr.sort((a, b) => a.name > b.name)

UPDATE: Funktioniert nicht immer, ist also nicht korrekt :(

18
Damjan Pavlica

Ich habe nicht gesehen, dass dieser spezielle Ansatz vorgeschlagen wurde. Deshalb hier eine knappe Vergleichsmethode, die ich gerne verwende und die sowohl für string als auch number funktioniert:

const objs = [ 
  { first_nom: 'Lazslo', last_nom: 'Jamf'     },
  { first_nom: 'Pig',    last_nom: 'Bodine'   },
  { first_nom: 'Pirate', last_nom: 'Prentice' }
];

const sortBy = fn => (a, b) => {
  const fa = fn(a)
  const fb = fn(b)
  return -(fa < fb) || +(fa > fb)
}
const getLastName = o => o.last_nom
const sortByLastName = sortBy(getLastName)

objs.sort(sortByLastName)
console.log(objs.map(getLastName))

Hier ist eine Erklärung von sortBy():

sortBy() akzeptiert einen fn, der auswählt, welcher Wert von einem Objekt als Vergleich verwendet werden soll, und gibt eine Funktion zurück, die direkt an Array.prototype.sort() übergeben werden kann. In diesem Beispiel verwenden wir o.last_nom als Vergleichswert, wenn wir also zwei Objekte über Array.prototype.sort() empfangen, z

{ first_nom: 'Lazslo', last_nom: 'Jamf' }

und

{ first_nom: 'Pig', last_nom: 'Bodine' }

wir gebrauchen

(a, b) => {
  const fa = fn(a)
  const fb = fn(b)
  return -(fa < fb) || +(fa > fb)
}

um sie zu vergleichen.

Wenn wir uns an fn = o => o.last_nom erinnern, können wir die Vergleichsfunktion auf das Äquivalent erweitern

(a, b) => {
  const fa = a.last_nom
  const fb = b.last_nom
  return -(fa < fb) || +(fa > fb)
}

Der logische Operator OR || verfügt über eine Kurzschlussfunktion, die hier sehr nützlich ist. Aufgrund der Funktionsweise bedeutet der Körper der obigen Funktion

if (fa < fb) return -1
return +(fa > fb)

Also, wenn fa < fb wir -1 zurückgeben, andernfalls, wenn fa > fb dann wir +1 zurückgeben, aber wenn fa == fb, dann fa < fb und fa > fb sind false, daher wird +0 zurückgegeben.

Als zusätzlichen Bonus gibt es hier das Äquivalent in ECMAScript 5 ohne Pfeilfunktionen, das leider ausführlicher ist:

var objs = [ 
  { first_nom: 'Lazslo', last_nom: 'Jamf'     },
  { first_nom: 'Pig',    last_nom: 'Bodine'   },
  { first_nom: 'Pirate', last_nom: 'Prentice' }
];

var sortBy = function (fn) {
  return function (a, b) {
    var fa = fn(a)
    var fb = fn(b)
    return -(fa < fb) || +(fa > fb)
  }
}

var getLastName = function (o) { return o.last_nom }
var sortByLastName = sortBy(getLastName)

objs.sort(sortByLastName)
console.log(objs.map(getLastName))
17
Patrick Roberts

Ich weiß, dass diese Frage zu alt ist, aber ich habe keine ähnliche Implementierung wie meine gesehen.
Diese Version basiert auf der Schwartzschen Transformation .

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

Hier ist ein Beispiel, wie man es benutzt:

let games = [
  { name: 'Pako',              rating: 4.21 },
  { name: 'Hill Climb Racing', rating: 3.88 },
  { name: 'Angry Birds Space', rating: 3.88 },
  { name: 'Badland',           rating: 4.33 }
];

// sort by one attribute
console.log(sortByAttribute(games, 'name'));
// sort by mupltiple attributes
console.log(sortByAttribute(games, '-rating', 'name'));
15
a8m

Sortieren (mehr) komplexer Arrays von Objekten

Da Sie wahrscheinlich auf komplexere Datenstrukturen wie dieses Array stoßen, würde ich die Lösung erweitern.

TL; DR

Sind mehr steckbare Version basierend auf @ ege-Özcan ist sehr schön Antwort .

Problem

Ich bin auf folgendes gestoßen und konnte es nicht ändern. Ich wollte das Objekt auch nicht vorübergehend abflachen. Ich wollte Underscore/Lodash auch nicht verwenden, hauptsächlich aus Gründen der Leistung und des Spaßes, es selbst zu implementieren.

var People = [
   {Name: {name: "Name", surname: "Surname"}, Middlename: "JJ"},
   {Name: {name: "AAA", surname: "ZZZ"}, Middlename:"Abrams"},
   {Name: {name: "Name", surname: "AAA"}, Middlename: "Wars"}
];

Tor

Das Ziel ist es, es primär nach People.Name.name und sekundär nach People.Name.surname zu sortieren

Hindernisse

In der Basislösung wird jetzt die Klammernotation verwendet, um die Eigenschaften zu berechnen, nach denen dynamisch sortiert werden soll. Hier müssten wir jedoch die Klammer-Notation auch dynamisch konstruieren, da man erwarten würde, dass einige wie People['Name.name'] funktionieren würden - was nicht funktioniert.

Das einfache Ausführen von People['Name']['name'] ist dagegen statisch und ermöglicht nur das Herunterschalten der n -ten Ebene.

Lösung

Der Hauptzusatz besteht darin, den Objektbaum zu durchlaufen und den Wert des letzten Blattes, das Sie angeben müssen, sowie eines Zwischenblattes zu bestimmen.

var People = [
   {Name: {name: "Name", surname: "Surname"}, Middlename: "JJ"},
   {Name: {name: "AAA", surname: "ZZZ"}, Middlename:"Abrams"},
   {Name: {name: "Name", surname: "AAA"}, Middlename: "Wars"}
];

People.sort(dynamicMultiSort(['Name','name'], ['Name', '-surname']));
// Results in...
// [ { Name: { name: 'AAA', surname: 'ZZZ' }, Middlename: 'Abrams' },
//   { Name: { name: 'Name', surname: 'Surname' }, Middlename: 'JJ' },
//   { Name: { name: 'Name', surname: 'AAA' }, Middlename: 'Wars' } ]

// same logic as above, but strong deviation for dynamic properties 
function dynamicSort(properties) {
  var sortOrder = 1;
  // determine sort order by checking sign of last element of array
  if(properties[properties.length - 1][0] === "-") {
    sortOrder = -1;
    // Chop off sign
    properties[properties.length - 1] = properties[properties.length - 1].substr(1);
  }
  return function (a,b) {
    propertyOfA = recurseObjProp(a, properties)
    propertyOfB = recurseObjProp(b, properties)
    var result = (propertyOfA < propertyOfB) ? -1 : (propertyOfA > propertyOfB) ? 1 : 0;
    return result * sortOrder;
  };
}

/**
 * Takes an object and recurses down the tree to a target leaf and returns it value
 * @param  {Object} root - Object to be traversed.
 * @param  {Array} leafs - Array of downwards traversal. To access the value: {parent:{ child: 'value'}} -> ['parent','child']
 * @param  {Number} index - Must not be set, since it is implicit.
 * @return {String|Number}       The property, which is to be compared by sort.
 */
function recurseObjProp(root, leafs, index) {
  index ? index : index = 0
  var upper = root
  // walk down one level
  lower = upper[leafs[index]]
  // Check if last leaf has been hit by having gone one step too far.
  // If so, return result from last step.
  if (!lower) {
    return upper
  }
  // Else: recurse!
  index++
  // HINT: Bug was here, for not explicitly returning function
  // https://stackoverflow.com/a/17528613/3580261
  return recurseObjProp(lower, leafs, index)
}

/**
 * Multi-sort your array by a set of properties
 * @param {...Array} Arrays to access values in the form of: {parent:{ child: 'value'}} -> ['parent','child']
 * @return {Number} Number - number for sort algorithm
 */
function dynamicMultiSort() {
  var args = Array.prototype.slice.call(arguments); // slight deviation to base

  return function (a, b) {
    var i = 0, result = 0, numberOfProperties = args.length;
    // REVIEW: slightly verbose; maybe no way around because of `.sort`-'s nature
    // Consider: `.forEach()`
    while(result === 0 && i < numberOfProperties) {
      result = dynamicSort(args[i])(a, b);
      i++;
    }
    return result;
  }
}

Beispiel

Arbeitsbeispiel auf JSBin

14

Eine weitere Option:

var someArray = [...];

function generateSortFn(prop, reverse) {
    return function (a, b) {
        if (a[prop] < b[prop]) return reverse ? 1 : -1;
        if (a[prop] > b[prop]) return reverse ? -1 : 1;
        return 0;
    };
}

someArray.sort(generateSortFn('name', true));

sortiert standardmäßig aufsteigend.

11

Ein einfacher Weg:

objs.sort(function(a,b) {
  return b.last_nom.toLowerCase() < a.last_nom.toLowerCase();
});

Stellen Sie sicher, dass '.toLowerCase()' erforderlich ist, um Fehler beim Vergleichen von Zeichenfolgen zu vermeiden.

10
Caio Ladislau

Wenn Sie die dynamische Lösung von Ege mit der Idee von Vinay kombinieren, erhalten Sie eine robuste Lösung von Nice:

Array.prototype.sortBy = function() {
    function _sortByAttr(attr) {
        var sortOrder = 1;
        if (attr[0] == "-") {
            sortOrder = -1;
            attr = attr.substr(1);
        }
        return function(a, b) {
            var result = (a[attr] < b[attr]) ? -1 : (a[attr] > b[attr]) ? 1 : 0;
            return result * sortOrder;
        }
    }
    function _getSortFunc() {
        if (arguments.length == 0) {
            throw "Zero length arguments not allowed for Array.sortBy()";
        }
        var args = arguments;
        return function(a, b) {
            for (var result = 0, i = 0; result == 0 && i < args.length; i++) {
                result = _sortByAttr(args[i])(a, b);
            }
            return result;
        }
    }
    return this.sort(_getSortFunc.apply(null, arguments));
}

Verwendungszweck:

// Utility for printing objects
Array.prototype.print = function(title) {
    console.log("************************************************************************");
    console.log("**** "+title);
    console.log("************************************************************************");
    for (var i = 0; i < this.length; i++) {
        console.log("Name: "+this[i].FirstName, this[i].LastName, "Age: "+this[i].Age);
    }
}

// Setup sample data
var arrObj = [
    {FirstName: "Zach", LastName: "Emergency", Age: 35},
    {FirstName: "Nancy", LastName: "Nurse", Age: 27},
    {FirstName: "Ethel", LastName: "Emergency", Age: 42},
    {FirstName: "Nina", LastName: "Nurse", Age: 48},
    {FirstName: "Anthony", LastName: "Emergency", Age: 44},
    {FirstName: "Nina", LastName: "Nurse", Age: 32},
    {FirstName: "Ed", LastName: "Emergency", Age: 28},
    {FirstName: "Peter", LastName: "Physician", Age: 58},
    {FirstName: "Al", LastName: "Emergency", Age: 51},
    {FirstName: "Ruth", LastName: "Registration", Age: 62},
    {FirstName: "Ed", LastName: "Emergency", Age: 38},
    {FirstName: "Tammy", LastName: "Triage", Age: 29},
    {FirstName: "Alan", LastName: "Emergency", Age: 60},
    {FirstName: "Nina", LastName: "Nurse", Age: 54}
];

//Unit Tests
arrObj.sortBy("LastName").print("LastName Ascending");
arrObj.sortBy("-LastName").print("LastName Descending");
arrObj.sortBy("LastName", "FirstName", "-Age").print("LastName Ascending, FirstName Ascending, Age Descending");
arrObj.sortBy("-FirstName", "Age").print("FirstName Descending, Age Ascending");
arrObj.sortBy("-Age").print("Age Descending");
9
Mike R

zusätzliche desc-Parameter für Ege Özcan Code

function dynamicSort(property, desc) {
    if (desc) {
        return function (a, b) {
            return (a[property] > b[property]) ? -1 : (a[property] < b[property]) ? 1 : 0;
        }   
    }
    return function (a, b) {
        return (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
    }
}
9
Behnam Yousefi

Eine einfache Funktion, die ein Array von Objekten nach einer Eigenschaft sortiert

function sortArray(array, property, direction) {
    direction = direction || 1;
    array.sort(function compare(a, b) {
        let comparison = 0;
        if (a[property] > b[property]) {
            comparison = 1 * direction;
        } else if (a[property] < b[property]) {
            comparison = -1 * direction;
        }
        return comparison;
    });
    return array; // Chainable
}

Verwendungszweck:

var objs = [ 
    { first_nom: 'Lazslo', last_nom: 'Jamf'     },
    { first_nom: 'Pig',    last_nom: 'Bodine'   },
    { first_nom: 'Pirate', last_nom: 'Prentice' }
];

sortArray(objs, "last_nom"); // Asc
sortArray(objs, "last_nom", -1); // Desc
9
Francois Girard
objs.sort(function(a,b){return b.last_nom>a.last_nom})
8
Roshni Bokade

Gemäß Ihrem Beispiel müssen Sie nach zwei Feldern (Nachname, Vorname) sortieren, und nicht nach einem. Sie können die Bibliothek Alasql verwenden, um diese Sortierung in einer Zeile vorzunehmen:

var res = alasql('SELECT * FROM ? ORDER BY last_nom, first_nom',[objs]);

Versuchen Sie dieses Beispiel bei jsFiddle .

8
agershun

Möglicherweise müssen Sie sie in Kleinbuchstaben umwandeln, um Verwechslungen zu vermeiden.

objs.sort(function (a,b) {

var nameA=a.last_nom.toLowerCase(), nameB=b.last_nom.toLowerCase()

if (nameA < nameB)
  return -1;
if (nameA > nameB)
  return 1;
return 0;  //no sorting

})
7
Burak Keceli

Gegeben das ursprüngliche Beispiel:

var objs = [ 
    { first_nom: 'Lazslo', last_nom: 'Jamf'     },
    { first_nom: 'Pig',    last_nom: 'Bodine'   },
    { first_nom: 'Pirate', last_nom: 'Prentice' }
];

Nach mehreren Feldern sortieren:

objs.sort(function(left, right) {
    var last_nom_order = left.last_nom.localeCompare(right.last_nom);
    var first_nom_order = left.first_nom.localeCompare(right.first_nom);
    return last_nom_order || first_nom_order;
});

Anmerkungen

  • a.localeCompare(b) ist niversell unterstützt und gibt -1,0,1 zurück, wenn a<b, a==b, a>b.
  • || in der letzten Zeile gibt last_nom Priorität vor first_nom.
  • Die Subtraktion funktioniert bei numerischen Feldern: var age_order = left.age - right.age;
  • Negiere, um die Reihenfolge umzukehren, return -last_nom_order || -first_nom_order || -age_order;
7
Bob Stein
function compare(propName) {
    return function(a,b) {
        if (a[propName] < b[propName])
            return -1;
        if (a[propName] > b[propName])
            return 1;
        return 0;
    };
}

objs.sort(compare("last_nom"));
7
Evgenii

Dies ist ein einfaches Problem, ich weiß nicht, warum die Leute so komplexe Lösungen haben.
Eine einfache Sortierfunktion (basierend auf quick-sort Algorithmus):

function sortObjectsArray(objectsArray, sortKey)
        {
            // Quick Sort:
            var retVal;

            if (1 < objectsArray.length)
            {
                var pivotIndex = Math.floor((objectsArray.length - 1) / 2);  // middle index
                var pivotItem = objectsArray[pivotIndex];                    // value in the middle index
                var less = [], more = [];

                objectsArray.splice(pivotIndex, 1);                          // remove the item in the pivot position
                objectsArray.forEach(function(value, index, array)
                {
                    value[sortKey] <= pivotItem[sortKey] ?                   // compare the 'sortKey' proiperty
                        less.Push(value) :
                        more.Push(value) ;
                });

                retVal = sortObjectsArray(less, sortKey).concat([pivotItem], sortObjectsArray(more, sortKey));
            }
            else
            {
                retVal = objectsArray;
            }

            return retVal;
        }

Anwendungsbeispiel:

var myArr = 
        [
            { val: 'x', idx: 3 },
            { val: 'y', idx: 2 },
            { val: 'z', idx: 5 },
        ];
myArr = sortObjectsArray(myArr, 'idx');
6
Gil Epshtain

Mit Ramda

npm install ramda

import R from 'ramda'
var objs = [ 
    { first_nom: 'Lazslo', last_nom: 'Jamf'     },
    { first_nom: 'Pig',    last_nom: 'Bodine'   },
    { first_nom: 'Pirate', last_nom: 'Prentice' }
];
var ascendingSortedObjs = R.sortBy(R.prop('last_nom'), objs)
var descendingSortedObjs = R.reverse(ascendingSortedObjs)
6
Sridhar Sg

Ich habe gerade die dynamische Art von Ege Özcan verbessert, um tief in Objekte einzutauchen. Wenn die Daten so aussehen:

obj = [
    {
        a: { a: 1, b: 2, c: 3 },
        b: { a: 4, b: 5, c: 6 }
    },
    { 
        a: { a: 3, b: 2, c: 1 },
        b: { a: 6, b: 5, c: 4 }
}];

und wenn Sie es über a.a Eigenschaft sortieren möchten, denke ich, dass meine Verbesserung sehr gut hilft. Ich füge folgenden Objekten neue Funktionen hinzu:

Object.defineProperty(Object.prototype, 'deepVal', {
    enumerable: false,
    writable: true,
    value: function (propertyChain) {
        var levels = propertyChain.split('.');
        parent = this;
        for (var i = 0; i < levels.length; i++) {
            if (!parent[levels[i]])
                return undefined;
            parent = parent[levels[i]];
        }
        return parent;
    }
});

und geänderte _ dynamicSort Funktion return :

return function (a,b) {
        var result = ((a.deepVal(property) > b.deepVal(property)) - (a.deepVal(property) < b.deepVal(property)));
        return result * sortOrder;
    }

Und jetzt können Sie wie folgt nach a.a. sortieren:

obj.sortBy('a.a');

Siehe Commplete-Skript in JSFiddle

5
Morteza Tourani

Verwenden von xPrototype : https://github.com/reduardo7/xPrototype/blob/master/README.md#sortbycol1-col2-coln

var o = [ 
  { Name: 'Lazslo', LastName: 'Jamf'     },
  { Name: 'Pig',    LastName: 'Bodine'   },
  { Name: 'Pirate', LastName: 'Prentice' },
  { Name: 'Pag',    LastName: 'Bodine'   }
];


// Original
o.each(function (a, b) { console.log(a, b); });
/*
 0 Object {Name: "Lazslo", LastName: "Jamf"}
 1 Object {Name: "Pig", LastName: "Bodine"}
 2 Object {Name: "Pirate", LastName: "Prentice"}
 3 Object {Name: "Pag", LastName: "Bodine"}
*/


// Sort By LastName ASC, Name ASC
o.sortBy('LastName', 'Name').each(function(a, b) { console.log(a, b); });
/*
 0 Object {Name: "Pag", LastName: "Bodine"}
 1 Object {Name: "Pig", LastName: "Bodine"}
 2 Object {Name: "Lazslo", LastName: "Jamf"}
 3 Object {Name: "Pirate", LastName: "Prentice"}
*/


// Sort by LastName ASC and Name ASC
o.sortBy('LastName'.asc, 'Name'.asc).each(function(a, b) { console.log(a, b); });
/*
 0 Object {Name: "Pag", LastName: "Bodine"}
 1 Object {Name: "Pig", LastName: "Bodine"}
 2 Object {Name: "Lazslo", LastName: "Jamf"}
 3 Object {Name: "Pirate", LastName: "Prentice"}
*/


// Sort by LastName DESC and Name DESC
o.sortBy('LastName'.desc, 'Name'.desc).each(function(a, b) { console.log(a, b); });
/*
 0 Object {Name: "Pirate", LastName: "Prentice"}
 1 Object {Name: "Lazslo", LastName: "Jamf"}
 2 Object {Name: "Pig", LastName: "Bodine"}
 3 Object {Name: "Pag", LastName: "Bodine"}
*/


// Sort by LastName DESC and Name ASC
o.sortBy('LastName'.desc, 'Name'.asc).each(function(a, b) { console.log(a, b); });
/*
 0 Object {Name: "Pirate", LastName: "Prentice"}
 1 Object {Name: "Lazslo", LastName: "Jamf"}
 2 Object {Name: "Pag", LastName: "Bodine"}
 3 Object {Name: "Pig", LastName: "Bodine"}
*/
4
Eduardo Cuomo

Weg 1:

Sie können Underscore.js verwenden. Importieren Sie zuerst den Unterstrich.

 import * as _ from 'underscore';
 let SortedObjs = _.sortBy(objs, 'last_nom');

Möglichkeit 2: Verwenden Sie die Vergleichsfunktion.

function compare(first, second) {
     if (first.last_nom < second.last_nom)
         return -1;
     if (first.last_nom > second.last_nom)
       return 1;
    return 0;
 }

objs.sort(compare);
4
Harunur Rashid

Mit lodash oder Underscore ist es ein Kinderspiel

> const sortedList = _.orderBy(objs, [last_nom], [asc]); // asc or desc
3
karthik006

Für mich geht das. Hier bleibt ndefiniert bis zum Ende erhalten.

 function sort(items, property, direction) {

    function compare(a, b) {
      if(!a[property] && !b[property]) {
        return 0;
      } else if(a[property] && !b[property]) {
        return -1;
      } else if(!a[property] && b[property]) {
        return 1;
      } else {
        const value1 = a[property].toString().toUpperCase(); // ignore upper and lowercase
        const value2 = b[property].toString().toUpperCase(); // ignore upper and lowercase
        if (value1 < value2) {
          return direction === 0 ? -1 : 1;
        } else if (value1 > value2) {
          return direction === 0 ? 1 : -1;
        } else {
          return 0;
        }
        
      }
    }
    
    return items.sort(compare);
   } 
   
   var items = [
  { name: 'Edward', value: 21 },
  { name: 'Sharpe', value: 37 },
  { name: 'And', value: 45 },
  { name: 'The', value: -12 },
  { name: undefined, value: -12 },
  { name: 'Magnetic', value: 13 },
  { name: 'Zeros', value: 37 }
];
   console.log('Ascending Order:- ');
   console.log(sort(items, 'name', 0));
   console.log('Decending Order:- ');
   console.log(sort(items, 'name', 1));
    
    
3
chandan gupta

Ich geriet in das Problem, eine Reihe von Objekten mit wechselnder Priorität von Werten zu sortieren. Im Grunde möchte ich eine Reihe von Menschen nach ihrem Alter und dann nach dem Nachnamen sortieren - oder einfach nur nach dem Nachnamen, dem Namen. Ich denke, dass dies im Vergleich zu anderen Antworten die einfachste Lösung ist.

es wird beim Aufruf von sortPeoples verwendet (['array', 'of', 'properties'], reverse = false)

///////////////////////example array of peoples ///////////////////////

var peoples = [
    {name: "Zach", surname: "Emergency", age: 1},
    {name: "Nancy", surname: "Nurse", age: 1},
    {name: "Ethel", surname: "Emergency", age: 1},
    {name: "Nina", surname: "Nurse", age: 42},
    {name: "Anthony", surname: "Emergency", age: 42},
    {name: "Nina", surname: "Nurse", age: 32},
    {name: "Ed", surname: "Emergency", age: 28},
    {name: "Peter", surname: "Physician", age: 58},
    {name: "Al", surname: "Emergency", age: 58},
    {name: "Ruth", surname: "Registration", age: 62},
    {name: "Ed", surname: "Emergency", age: 38},
    {name: "Tammy", surname: "Triage", age: 29},
    {name: "Alan", surname: "Emergency", age: 60},
    {name: "Nina", surname: "Nurse", age: 58}
];



//////////////////////// Sorting function /////////////////////
function sortPeoples(propertyArr, reverse) {
        function compare(a,b) {
            var i=0;
            while (propertyArr[i]) {
                if (a[propertyArr[i]] < b[propertyArr[i]])  return -1;
                if (a[propertyArr[i]] > b[propertyArr[i]])  return 1;
                i++;
            }
            return 0;
            }
        peoples.sort(compare);
        if (reverse){
            peoples.reverse();
        }
    };

////////////////end of sorting method///////////////
function printPeoples(){
  $('#output').html('');
peoples.forEach( function(person){
 $('#output').append(person.surname+" "+person.name+" "+person.age+"<br>");
} )
}
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
  <html>
  <body>
<button onclick="sortPeoples(['surname']); printPeoples()">sort by ONLY by surname ASC results in mess with same name cases</button><br>
<button onclick="sortPeoples(['surname', 'name'], true); printPeoples()">sort by surname then name DESC</button><br>
<button onclick="sortPeoples(['age']); printPeoples()">sort by AGE ASC. Same issue as in first case</button><br>
<button onclick="sortPeoples(['age', 'surname']); printPeoples()">sort by AGE and Surname ASC. Adding second field fixed it.</button><br>
        
    <div id="output"></div>
    </body>
  </html>
2
jmwierzbicki
// Sort Array of Objects

// Data
var booksArray = [
    { first_nom: 'Lazslo', last_nom: 'Jamf'     },
    { first_nom: 'Pig',    last_nom: 'Bodine'   },
    { first_nom: 'Pirate', last_nom: 'Prentice' }
];

// Property to Sort By
var args = "last_nom";

// Function to Sort the Data by given Property
function sortByProperty(property) {
    return function (a, b) {
        var sortStatus = 0,
            aProp = a[property].toLowerCase(),
            bProp = b[property].toLowerCase();
        if (aProp < bProp) {
            sortStatus = -1;
        } else if (aProp > bProp) {
            sortStatus = 1;
        }
        return sortStatus;
    };
}

// Implementation
var sortedArray = booksArray.sort(sortByProperty(args));

console.log("sortedArray: " + JSON.stringify(sortedArray) );

Konsolenprotokollausgabe:

"sortedArray: 
[{"first_nom":"Pig","last_nom":"Bodine"},
{"first_nom":"Lazslo","last_nom":"Jamf"},
{"first_nom":"Pirate","last_nom":"Prentice"}]"

Basierend auf dieser Quelle angepasst: http://www.levihackwith.com/code-snippet-how-to-sort-an-array-of-json-objects-by-property/

2
Luke Schoen

Dadurch wird ein verschachteltes Array mit zwei Ebenen nach der übergebenen Eigenschaft in alphanumerischer Reihenfolge sortiert.

function sortArrayObjectsByPropAlphaNum(property) {
    return function (a,b) {
        var reA = /[^a-zA-Z]/g;
        var reN = /[^0-9]/g;
        var aA = a[property].replace(reA, '');
        var bA = b[property].replace(reA, '');

        if(aA === bA) {
            var aN = parseInt(a[property].replace(reN, ''), 10);
            var bN = parseInt(b[property].replace(reN, ''), 10);
            return aN === bN ? 0 : aN > bN ? 1 : -1;
        } else {
            return a[property] > b[property] ? 1 : -1;
        }
    };
}

Verwendungszweck:

objs.sort(utils.sortArrayObjectsByPropAlphaNum('last_nom'));
2
depiction

Hier ist also ein Sortieralgorithmus, der in beliebiger Reihenfolge in einem Array von Objekten aller Art sortieren kann, ohne die Einschränkung des Datentypvergleichs (d. H. Zahl, Zeichenfolge).

function smoothSort(items,prop,reverse) {  
    var length = items.length;
    for (var i = (length - 1); i >= 0; i--) {
        //Number of passes
        for (var j = (length - i); j > 0; j--) {
            //Compare the adjacent positions
            if(reverse){
              if (items[j][prop] > items[j - 1][prop]) {
                //Swap the numbers
                var tmp = items[j];
                items[j] = items[j - 1];
                items[j - 1] = tmp;
            }
            }

            if(!reverse){
              if (items[j][prop] < items[j - 1][prop]) {
                  //Swap the numbers
                  var tmp = items[j];
                  items[j] = items[j - 1];
                  items[j - 1] = tmp;
              }
            }
        }
    }

    return items;
}
  • das erste Argument items ist das Array von Objekten,

  • prop ist der Schlüssel des Objekts, nach dem Sie sortieren möchten,

  • reverse ist ein boolescher Parameter, der bei Wahr in aufsteigender Reihenfolge und bei Falsch in absteigender Reihenfolge zurückgibt.

2
Partha Roy

Ich werde Ihnen eine Lösung geben, die den selectionSort-Algorithmus implementiert. Er ist einfach und effektiv

var objs = [ 
{ first_nom: 'Lazslo', last_nom: 'Jamf'     },
{ first_nom: 'Pig',    last_nom: 'Bodine'   },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];


function selection_Sort(num) { 
 //console.log(num);  
 var temp, index;
 for (var i = 0; i <= num.length - 1; i++) {
index = i;
for (var j = i + 1; j <= num.length - 1; j++) {
 // you can use first_nom/last_nom,any way you choose to sort

  if (num[j]. last_nom < num[index]. last_nom) {
    index = j;
  } 
}

//below is the swapping part
temp = num[i]. last_nom;
num[i]. last_nom = num[index]. last_nom;
num[index]. last_nom = temp;
 };
 console.log(num); 
 return num; 
  }
  selection_Sort(objs);

Schön, so tolle Antworten zu sehen

1
sg28

Für den Fall, dass Sie Objekte verschachtelt haben

const objs = [{
        first_nom: 'Lazslo',
        last_nom: 'Jamf',
        moreDetails: {
            age: 20
        }
    }, {
        first_nom: 'Pig',
        last_nom: 'Bodine',
        moreDetails: {
            age: 21
        }
    }, {
        first_nom: 'Pirate',
        last_nom: 'Prentice',
        moreDetails: {
            age: 22
        }
    }];

nestedSort = (prop1, prop2 = null, direction = 'asc') => (e1, e2) => {
        const a = prop2 ? e1[prop1][prop2] : e1[prop1],
            b = prop2 ? e2[prop1][prop2] : e2[prop1],
            sortOrder = direction === "asc" ? 1 : -1
        return (a < b) ? -sortOrder : (a > b) ? sortOrder : 0;
    }

und nenne es wie

objs.sort(nestedSort("last_nom"));
objs.sort(nestedSort("last_nom", null, "desc"));
objs.sort(nestedSort("moreDetails", "age"));
objs.sort(nestedSort("moreDetails", "age", "desc"));
0
Mas

Es ist auch möglich, eine dynamische Sortierfunktion beim Programmieren in TypeScript zu erstellen, aber die Typen werden in diesem Fall schwieriger.

function sortByKey<O>(key: keyof O, decending: boolean = false): (a: O, b: O) => number {
    const order = decending ? -1 : 1;
    return (a, b): number => {
        const valA = a[key];
        const valB = b[key];
        if (valA < valB) {
            return -order;
        } else if (valA > valB) {
            return order;
        } else {
            return 0;
        }
    }
}

Dies kann in TypeScript wie folgt verwendet werden:

const test = [
    {
        id: 0,
    },
    {
        id: 2,
    }
]

test.sort(sortByKey('id')) // OK
test.sort(sortByKey('id1')) // ERROR
test.sort(sortByKey('')) // ERROR
0
Ferrybig