Objekte nach Eigenschaftswerten sortieren

85

So implementieren Sie das folgende Szenario nur mit Javascript:

  • Erstellen Sie ein Auto - Objekt mit Eigenschaften (Höchstgeschwindigkeit, Marke, etc.)
  • Sortieren Sie eine Liste der nach diesen Eigenschaften geordneten Autos
Konstrukteur
quelle
3
@durilai: JavaScript ist objektorientiert, das OO-Modell von JavaScript basiert auf Prototyping und ist wirklich sehr, sehr vielseitig ... en.wikipedia.org/wiki/Prototype-based_programming
Christian C. Salvadó
Ich empfehle, lodash.js zu verwenden: lodash.com/docs#sortBy
Chemical Programmer

Antworten:

158

Javascript hat die Sortierfunktion , die eine andere Funktion als Parameter annehmen kann - diese zweite Funktion wird verwendet, um zwei Elemente zu vergleichen.

Beispiel:

cars = [

    {
        name: "Honda",
        speed: 80
    },

    {
        name: "BMW",
        speed: 180
    },

    {
        name: "Trabi",
        speed: 40
    },

    {
        name: "Ferrari",
        speed: 200
    }
]


cars.sort(function(a, b) { 
    return a.speed - b.speed;
})

for(var i in cars)
    document.writeln(cars[i].name) // Trabi Honda BMW Ferrari 

ok, aus deinem Kommentar sehe ich, dass du das Wort 'sort' im falschen Sinne verwendest. In der Programmierung bedeutet "sortieren" "Dinge in eine bestimmte Reihenfolge bringen", nicht "Dinge in Gruppen anordnen". Letzteres ist viel einfacher - so "sortieren" Sie die Dinge in der realen Welt

  • mache zwei leere Arrays ("Boxen")
  • Überprüfen Sie für jedes Objekt in Ihrer Liste, ob es den Kriterien entspricht
  • Wenn ja, geben Sie es in die erste "Box" ein.
  • Wenn nein, legen Sie es in die zweite "Box"
user187291
quelle
10
Einfacher Hinweis zur Vereinfachung: this ( a.someProp - b.someProp) sortiert vom niedrigsten zum höchsten und das reverse ( b.someProp - a.someProp) vom höchsten zum niedrigsten. Wenn die Funktion weniger als 0 zurückgibt, steht a
user56reinstatemonica8
Beachten Sie auch, dass diese Lösung nur funktioniert, wenn die Eigenschaften, nach denen Sie sortieren, Zahlen sind. Dies funktioniert im Beispiel für das Sortieren nach Höchstgeschwindigkeit. Wenn Sie jedoch nach Automarke sortieren möchten, sortiert diese Lösung Zeichenfolgen nicht alphabetisch. Cheeso bietet eine Antwort zum Sortieren nach Zahlen und Zeichenfolgen.
Cole Marshall
23

Beispiel.

Dies läuft auf cscript.exe unter Windows.

// define the Car class
(function() {
    // makeClass - By John Resig (MIT Licensed)
    // Allows either new User() or User() to be employed for construction.
    function makeClass(){
        return function(args){
            if ( this instanceof arguments.callee ) {
                if ( typeof this.init == "function" )
                    this.init.apply( this, (args && args.callee) ? args : arguments );
            } else
                return new arguments.callee( arguments );
        };
    }

    Car = makeClass();

    Car.prototype.init = function(make, model, price, topSpeed, weight) {
        this.make = make;
        this.model = model;
        this.price = price;
        this.weight = weight;
        this.topSpeed = topSpeed;
    };
})();


// create a list of cars
var autos = [
    new Car("Chevy", "Corvair", 1800, 88, 2900),
    new Car("Buick", "LeSabre", 31000, 138, 3700),
    new Car("Toyota", "Prius", 24000, 103, 3200),
    new Car("Porsche", "911", 92000, 155, 3100),
    new Car("Mercedes", "E500", 67000, 145, 3800),
    new Car("VW", "Passat", 31000, 135, 3700)
];

// a list of sorting functions
var sorters = {
    byWeight : function(a,b) {
        return (a.weight - b.weight);
    },
    bySpeed : function(a,b) {
        return (a.topSpeed - b.topSpeed);
    },
    byPrice : function(a,b) {
        return (a.price - b.price);
    },
    byModelName : function(a,b) {
        return ((a.model < b.model) ? -1 : ((a.model > b.model) ? 1 : 0));
    },
    byMake : function(a,b) {
        return ((a.make < b.make) ? -1 : ((a.make > b.make) ? 1 : 0));
    }
};

function say(s) {WScript.Echo(s);}

function show(title)
{
    say ("sorted by: "+title);
    for (var i=0; i < autos.length; i++) {
        say("  " + autos[i].model);
    }
    say(" ");
}

autos.sort(sorters.byWeight);
show("Weight");

autos.sort(sorters.byModelName);
show("Name");

autos.sort(sorters.byPrice);
show("Price");

Sie können auch einen allgemeinen Sortierer erstellen.

var byProperty = function(prop) {
    return function(a,b) {
        if (typeof a[prop] == "number") {
            return (a[prop] - b[prop]);
        } else {
            return ((a[prop] < b[prop]) ? -1 : ((a[prop] > b[prop]) ? 1 : 0));
        }
    };
};

autos.sort(byProperty("topSpeed"));
show("Top Speed");
Cheeso
quelle
13

Ich habe diese einfache Funktion für mich selbst geschrieben:

function sortObj(list, key) {
    function compare(a, b) {
        a = a[key];
        b = b[key];
        var type = (typeof(a) === 'string' ||
                    typeof(b) === 'string') ? 'string' : 'number';
        var result;
        if (type === 'string') result = a.localeCompare(b);
        else result = a - b;
        return result;
    }
    return list.sort(compare);
}

Zum Beispiel haben Sie eine Liste von Autos:

var cars= [{brand: 'audi', speed: 240}, {brand: 'fiat', speed: 190}];
var carsSortedByBrand = sortObj(cars, 'brand');
var carsSortedBySpeed = sortObj(cars, 'speed');
Slavugan
quelle
6

Nehmen wir an, wir müssen eine Liste von Objekten in aufsteigender Reihenfolge nach einer bestimmten Eigenschaft sortieren. In diesem Beispiel müssen wir nach der Eigenschaft "name" sortieren. Nachfolgend finden Sie den erforderlichen Code:

var list_Objects = [{"name"="Bob"},{"name"="Jay"},{"name"="Abhi"}];
Console.log(list_Objects);   //[{"name"="Bob"},{"name"="Jay"},{"name"="Abhi"}]
    list_Objects.sort(function(a,b){
        return a["name"].localeCompare(b["name"]); 
    });
Console.log(list_Objects);  //[{"name"="Abhi"},{"name"="Bob"},{"name"="Jay"}]
Jayanth G.
quelle
1
Ich denke du hast einen Tippfehler? return a ["name"]. localeCompare (b. ["name"]); sollte a ["name"] zurückgeben. localeCompare (b ["name"]); (Entfernen Sie die. nach b)
Little Brain
3

Mit den ES6-Pfeilfunktionen sieht es so aus:

//Let's say we have these cars
let cars = [ { brand: 'Porsche', top_speed: 260 },
  { brand: 'Benz', top_speed: 110 },
  { brand: 'Fiat', top_speed: 90 },
  { brand: 'Aston Martin', top_speed: 70 } ]

Array.prototype.sort() kann eine Komparatorfunktion akzeptieren (hier habe ich die Pfeilnotation verwendet, aber gewöhnliche Funktionen funktionieren genauso):

let sortedByBrand = [...cars].sort((first, second) => first.brand > second.brand)

// [ { brand: 'Aston Martin', top_speed: 70 },
//   { brand: 'Benz', top_speed: 110 },
//   { brand: 'Fiat', top_speed: 90 },
//   { brand: 'Porsche', top_speed: 260 } ]

Der obige Ansatz kopiert den Inhalt des Fahrzeugarrays in ein neues und sortiert es alphabetisch nach Markennamen. Ebenso können Sie eine andere Funktion übergeben:

let sortedBySpeed =[...cars].sort((first, second) => first.top_speed > second.top_speed)

//[ { brand: 'Aston Martin', top_speed: 70 },
//  { brand: 'Fiat', top_speed: 90 },
//  { brand: 'Benz', top_speed: 110 },
//  { brand: 'Porsche', top_speed: 260 } ]

Wenn es Ihnen nichts ausmacht, das ursprüngliche Array zu mutieren cars.sort(comparatorFunction), reicht dies aus.

Farzad Schwindel
quelle
3

Hier ist ein kurzes Beispiel, das Objekte erstellt und anordnet und numerisch oder alphabetisch sortiert:

// Create Objects Array

var arrayCarObjects = [
{brand: "Honda",        topSpeed: 45},
{brand: "Ford",         topSpeed: 6},
{brand: "Toyota",       topSpeed: 240},
{brand: "Chevrolet",    topSpeed: 120},
{brand: "Ferrari",      topSpeed: 1000}
];

// Sort Objects Numerically

arrayCarObjects.sort((a, b) => (a.topSpeed - b.topSpeed));

// Sort Objects Alphabetically

arrayCarObjects.sort((a, b) => (a.brand > b.brand) ? 1 : -1);
theMaxx
quelle
2

Als Version der Cheeso-Lösung mit umgekehrter Sortierung habe ich auch die ternären Ausdrücke aus Gründen der Unklarheit entfernt (dies ist jedoch ein persönlicher Geschmack).

function(prop, reverse) {
  return function(a, b) {
    if (typeof a[prop] === 'number') {
      return (a[prop] - b[prop]);
    }

    if (a[prop] < b[prop]) {
      return reverse ? 1 : -1;
    }

    if (a[prop] > b[prop]) {
      return reverse ? -1 : 1;
    }

    return 0;
  };
};
Marcs
quelle
1
Um vollständig umgekehrt zu werden, müssen die Zahlenreturn !!reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
Mark Schultheiss
Ja, da jetzt keine umgekehrte Überprüfung der Zahlen erfolgt, danke, das sollte ich beheben. Aber warum das Doppel !ist das auch in Ordnung:return reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
Marcs
1
Der !!Force-Typ-Zwang zu einem nativen booleschen Typ-Wert im Gegensatz zur "Falschheit" des JavaScript-Werts, der nicht unbedingt benötigt wird, aber zumindest für mich den Zweck klarstellt. Beachten Sie, dass , wenn Sie einen Wert zurückgeben mit !!einem nativen Booleschen Typ ist wie bei einem „falsy“ Wert auf einen nativen Typ gegenüber, das das zu sagen ist typeof !!undefinedoder typeof !!nullusw. Rückkehr „boolean“ Beachten Sie, dass !!" "ist trueaber !!""ist false(Raum, keinen Platz in der string) aber das wusstest du wahrscheinlich schon.
Mark Schultheiss