Menyortir objek berdasarkan nilai properti


88

Cara menerapkan skenario berikut hanya menggunakan Javascript:

  • Buat objek mobil dengan properti (kecepatan tertinggi, merek, dll.)
  • Urutkan daftar mobil yang dipesan berdasarkan properti tersebut

3
@durilai: JavaScript adalah berorientasi objek, model OO dari JavaScript berdasarkan Prototyping dan benar-benar, benar-benar serbaguna ... en.wikipedia.org/wiki/Prototype-based_programming
Christian C. Salvado

Saya merekomendasikan untuk menggunakan lodash.js: lodash.com/docs#sortBy
Programmer Kimia

Jawaban:


162

javascript memiliki fungsi sort yang dapat mengambil fungsi lain sebagai parameter - fungsi kedua digunakan untuk membandingkan dua elemen.

Contoh:

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, dari komentar Anda saya melihat bahwa Anda menggunakan kata 'sort' dalam arti yang salah. Dalam pemrograman "mengurutkan" berarti "meletakkan sesuatu dalam urutan tertentu", bukan "mengatur sesuatu dalam kelompok". Yang terakhir jauh lebih sederhana - ini hanyalah cara Anda "menyortir" hal-hal di dunia nyata

  • buat dua larik kosong ("kotak")
  • untuk setiap objek dalam daftar Anda, periksa apakah sesuai dengan kriteria
  • jika ya, taruh di "kotak" pertama
  • jika tidak, taruh di "kotak" kedua

11
Catatan sederhana untuk kenyamanan: this ( a.someProp - b.someProp) mengurutkan dari terendah ke tertinggi , dan reverse ( b.someProp - a.someProp) mengurutkan dari tertinggi ke terendah. Pada dasarnya, jika fungsi mengembalikan kurang dari 0, a muncul sebelum b.
user56reinstatemonica8

Perhatikan juga bahwa solusi ini hanya berfungsi jika properti yang Anda sortir adalah angka. Ini berfungsi dalam contoh untuk mengurutkan berdasarkan kecepatan tertinggi, tetapi jika Anda ingin mengurutkan berdasarkan merek mobil, solusi ini tidak akan mengurutkan string menurut abjad. Cheeso memberikan jawaban untuk pengurutan berdasarkan angka dan string.
Cole Marshall

23

Contoh.

Ini berjalan di cscript.exe, di 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");

Anda juga bisa membuat penyortir umum.

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

Saya telah menulis fungsi sederhana ini untuk diri saya sendiri:

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

misalnya Anda memiliki daftar mobil:

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

6

Katakanlah kita harus mengurutkan daftar objek dalam urutan menaik berdasarkan properti tertentu, dalam contoh ini katakanlah kita harus mengurutkan berdasarkan properti "nama", kemudian di bawah ini adalah kode yang diperlukan:

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
Saya pikir Anda salah ketik? mengembalikan ["nama"]. localeCompare (b. ["name"]); harus mengembalikan ["nama"]. localeCompare (b ["name"]); (hapus. setelah b)
Little Brain

3

Dengan fungsi panah ES6 akan menjadi seperti ini:

//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() dapat menerima fungsi pembanding (di sini saya menggunakan notasi panah, tetapi fungsi biasa bekerja sama):

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

Pendekatan di atas menyalin isi deretan mobil ke yang baru dan mengurutkannya berdasarkan abjad berdasarkan nama merek. Demikian pula, Anda dapat meneruskan fungsi yang berbeda:

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

Jika Anda tidak keberatan memutasi array asli cars.sort(comparatorFunction)akan berhasil.


3

Berikut adalah contoh singkatnya, yang membuat dan menyusun objek, dan mengurutkan menurut angka atau abjad:

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

Versi solusi Cheeso dengan penyortiran terbalik, saya juga menghapus ekspresi terner karena kurangnya kejelasan (tetapi ini adalah selera pribadi).

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
Untuk sepenuhnya dibalik kebutuhan angkareturn !!reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
Mark Schultheiss

Ya, karena sekarang tidak ada pemeriksaan balik pada nomor, terima kasih, saya harus memperbaikinya. Tapi mengapa ganda !ini bagus juga:return reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
Marcs

1
The !!jenis pasukan paksaan untuk nilai jenis asli boolean yang bertentangan dengan sifat "falsy" dari nilai JavaScript, tidak ketat diperlukan tapi memperjelas tujuan setidaknya untuk saya. Perhatikan bahwa ketika Anda mengembalikan nilai !!dengannya adalah jenis Boolean asli yang bertentangan dengan jenis asli dengan nilai "falsy" yang mengatakan typeof !!undefinedatau typeof !!nulldll. Mengembalikan "boolean" Perhatikan bahwa !!" "is truebut !!""is false(spasi, tidak ada spasi di string) tetapi Anda mungkin sudah mengetahuinya.
Mark Schultheiss
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.