Pertanyaan Urutkan susunan objek berdasarkan nilai properti string dalam JavaScript


Saya memiliki larik objek JavaScript:

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

Bagaimana saya bisa mengurutkannya berdasarkan nilai last_nom di JavaScript?

Saya tahu tentang sort(a,b), tetapi itu sepertinya hanya bekerja pada string dan angka. Apakah saya perlu menambahkan metode toString ke objek saya?


1815
2017-07-15 03:17


asal


Jawaban:


Cukup mudah untuk menulis fungsi perbandingan Anda sendiri:

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

Atau sebaris (c / o Marco Demaio):

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

2695
2017-07-15 03:35



Anda juga dapat membuat fungsi sortir dinamis yang mengurutkan objek berdasarkan nilainya yang Anda lewati:

function dynamicSort(property) {
    var sortOrder = 1;
    if(property[0] === "-") {
        sortOrder = -1;
        property = property.substr(1);
    }
    return function (a,b) {
        var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
        return result * sortOrder;
    }
}

Jadi Anda dapat memiliki larik objek seperti ini:

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

... dan itu akan berfungsi ketika Anda melakukannya:

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

Sebenarnya ini sudah menjawab pertanyaan. Bagian bawah ditulis karena banyak orang menghubungi saya, mengeluh itu itu tidak berfungsi dengan beberapa parameter.

Beberapa Parameter

Anda dapat menggunakan fungsi di bawah ini untuk menghasilkan fungsi pengurutan dengan beberapa parameter pengurutan.

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

Yang memungkinkan Anda melakukan sesuatu seperti ini:

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

Menambahkannya ke Prototipe

(Implementasi yang tepat di bawah ini terinspirasi dari Mike R's menjawab)

Saya tidak akan merekomendasikan mengubah prototipe objek asli tetapi hanya untuk memberikan contoh sehingga Anda dapat menerapkannya pada objek Anda sendiri (Untuk lingkungan yang mendukungnya, Anda juga bisa menggunakan Object.defineProperty seperti yang diperlihatkan pada bagian berikutnya, yang setidaknya tidak memiliki efek samping negatif yang dapat dihitung, seperti yang dijelaskan pada bagian terakhir)

Implementasi prototipe akan menjadi sesuatu seperti berikut (Berikut ini contoh kerja):

//Don't just copy-paste this code. You will break the "for-in" loops
!function() {
    function _dynamicSortMultiple(attr) {
       /* dynamicSortMultiple function body comes here */
    }
    function _dynamicSort(property) {
        /* dynamicSort function body comes here */
    }
    Array.prototype.sortBy = function() {
        return this.sort(_dynamicSortMultiple.apply(null, arguments));
    }
}();

The "OK" Cara Menambahkannya Ke Prototype

Jika Anda menargetkan IE v9.0 dan kemudian, seperti yang saya sebutkan sebelumnya, gunakan Object.defineProperty seperti ini (contoh kerja):

//Won't work below IE9, but totally safe otherwise
!function() {
    function _dynamicSortMultiple(attr) {
       /* dynamicSortMultiple function body comes here */
    }
    function _dynamicSort(property) {
        /* dynamicSort function body comes here */
    }
    Object.defineProperty(Array.prototype, "sortBy", {
        enumerable: false,
        writable: true,
        value: function() {
            return this.sort(_dynamicSortMultiple.apply(null, arguments));
        }
    });
}();

Ini bisa menjadi kompromi yang dapat diterima sampai mengikat operator tiba.

Semua kesenangan prototipe ini memungkinkan ini:

People.sortBy("Name", "-Surname");

Anda Harus Baca Ini

Jika Anda menggunakan metode akses prototipe langsung (Object.defineProperty baik-baik saja) dan kode lain tidak memeriksa hasOwnProperty, anak kucing mati! Ok, jujur ​​saja, tidak ada bahaya yang datang pada anak kucing apa pun, tetapi mungkin hal-hal akan rusak dan setiap pengembang di tim Anda akan membenci Anda:

evil

Lihat yang terakhir "SortBy"? Ya. Tidak keren. Gunakan Object.defineProperty di mana Anda bisa, dan biarkan Array.prototype sendiri sebaliknya.


649
2018-01-21 15:03



underscore.js

gunakan underscore, yang kecil dan mengagumkan ...

sortBy_.sortBy (daftar, iterator, [konteks]) Mengembalikan salinan yang disortir   daftar, diurutkan dalam urutan naik berdasarkan hasil menjalankan setiap nilai   melalui iterator. Iterator juga bisa menjadi nama string properti   untuk mengurutkan berdasarkan (mis. panjang).

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

155
2018-05-10 21:24



Jangan mengerti mengapa orang membuatnya begitu rumit:

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

Untuk mesin yang lebih ketat:

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

Tukar operator untuk memilahnya berdasarkan urutan abjad terbalik.


140
2018-01-24 19:35



Di ES6 / ES2015 atau lebih baru Anda dapat melakukan cara ini:

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

136
2018-01-29 19:44



Jika Anda memiliki duplikat nama belakang Anda mungkin mengurutkan nama depan-

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

51
2017-07-15 04:03



Solusi sederhana dan cepat untuk masalah ini menggunakan warisan prototipe:

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

Contoh / Penggunaan

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

Memperbarui: Tidak lagi memodifikasi larik orisinal.


38
2017-07-10 11:54



Alih-alih menggunakan fungsi perbandingan khusus, Anda juga bisa membuat jenis objek dengan kustom toString() metode (yang dipanggil oleh fungsi perbandingan standar):

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

23
2017-07-15 07:21