Nesneleri özellik değerlerine göre sıralama


88

Aşağıdaki senaryo yalnızca Javascript kullanılarak nasıl uygulanır:

  • Özelliklerle (en yüksek hız, marka vb.) Bir araba nesnesi oluşturun
  • Bu özelliklere göre sıralanmış bir araba listesini sıralayın

3
@durilai: JavaScript edilir nesne yönelimli, JavaScript OO modeli dayanmaktadır Prototip ve gerçekten, gerçekten çok yönlü ... en.wikipedia.org/wiki/Prototype-based_programming
Christian C. Salvadó

Lodash.js kullanmanızı tavsiye ederim: lodash.com/docs#sortBy
Kimyasal Programcı

Yanıtlar:


162

javascript, parametre olarak başka bir işlevi alabilen sıralama işlevine sahiptir - bu ikinci işlev, iki öğeyi karşılaştırmak için kullanılır.

Misal:

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 

Tamam, yorumunuzdan 'sırala' kelimesini yanlış bir anlamda kullandığınızı görüyorum. Programlamada "sıralama", "şeyleri gruplar halinde düzenleme" değil, "işleri belirli bir sıraya koyma" anlamına gelir. İkincisi çok daha basit - bu, gerçek dünyada olayları nasıl "sıraladığınız"

  • iki boş dizi ("kutular") yapın
  • listenizdeki her nesne için kriterlere uyup uymadığını kontrol edin
  • evet ise, ilk "kutuya" koyun
  • hayır ise, ikinci "kutuya" koyun

11
Kolaylık sağlamak için basit bir not: this ( a.someProp - b.someProp) en düşükten en yükseğe , reverse ( b.someProp - a.someProp) en yüksekten en düşüğe doğru sıralar. Temel olarak, fonksiyon 0'dan küçük dönerse, a, b'den önce gelir.
user56reinstatemonica8

Ayrıca, bu çözümün yalnızca sıraladığınız özellikler sayı olduğunda işe yaradığını unutmayın. Bu, en yüksek hıza göre sıralama örneğinde işe yarar, ancak araba markasına göre sıralamak istiyorsanız, bu çözüm dizeleri alfabetik olarak sıralamaz. Cheeso, hem sayılara hem de dizelere göre sıralama için bir cevap sağlar.
Cole Marshall

23

Misal.

Bu, Windows'ta cscript.exe üzerinde çalışır.

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

Ayrıca genel bir sıralayıcı da yapabilirsiniz.

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

13

Bu basit işlevi kendim için yazdım:

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

örneğin araba listeniz var:

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

6

Belirli bir özelliğe dayalı olarak nesnelerin bir listesini artan sırada sıralamamız gerektiğini varsayalım, bu örnekte "name" özelliğine göre sıralama yapmamız gerektiğini varsayalım, ardından gerekli kod aşağıdadır:

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

1
Sanırım bir yazım hatası mı var? bir ["ad"] döndür. localeCompare (b. ["ad"]); bir ["ad"] döndürülmelidir. localeCompare (b ["ad"]); (b'den sonra. kaldırın)
Little Brain

3

İle ES6 ok fonksiyonları şekilde olacaktır:

//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() bir karşılaştırıcı işlevi kabul edebilir (burada ok gösterimini kullandım, ancak sıradan işlevler aynı şekilde çalışır):

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

Yukarıdaki yaklaşım, araba dizisinin içeriğini yenisine kopyalar ve marka adlarına göre alfabetik olarak sıralar. Benzer şekilde, farklı bir işlevi de geçebilirsiniz:

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

Orjinal diziyi değiştirmenin bir sakıncası cars.sort(comparatorFunction)yoksa hile yapacak.


3

Nesneleri oluşturan ve sıralayan ve sayısal veya alfabetik olarak sıralayan kısa bir örnek:

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

2

Ters sıralama ile Cheeso çözümünün bir versiyonu, netlik eksikliği nedeniyle üçlü ifadeleri de kaldırdım (ama bu kişisel zevk).

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

1
Sayıların tamamen tersine çevrilmesi için gerekenreturn !!reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
Mark Schultheiss

Evet, şimdi sayılar üzerinde ters kontrol olmadığından, teşekkür ederim, bunu düzeltmeliyim. Ama neden duble !bu da iyi:return reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
Marcs

1
!!JavaScript değerinin "falsy" doğaya karşı bir yerli boole tip değerine güçler tip zorlama, kesinlikle gerekli ama açıklık getirmektedir amacı, en azından benim için değil. Not bununla Bir değer döndüğünüzde !!söylemek bir "falsy" değerine sahip bir yerli tip aksine bir yerli Boole türüdür typeof !!undefinedya typeof !!nullvs. dönüş "boolean" Not !!" "olduğunu trueama !!""olan false(boşluk, hiçbir boşluk string) ama muhtemelen bunu zaten biliyordunuz.
Mark Schultheiss
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.