Saya mencoba mengurutkan array dengan objek berdasarkan beberapa atribut. Yaitu jika atribut pertama adalah sama antara dua objek, atribut kedua harus digunakan untuk membandingkan kedua objek. Misalnya, perhatikan larik berikut:
var patients = [
[{name: 'John', roomNumber: 1, bedNumber: 1}],
[{name: 'Lisa', roomNumber: 1, bedNumber: 2}],
[{name: 'Chris', roomNumber: 2, bedNumber: 1}],
[{name: 'Omar', roomNumber: 3, bedNumber: 1}]
];
Menyortir ini berdasarkan roomNumber
atribut saya akan menggunakan kode berikut:
var sortedArray = _.sortBy(patients, function(patient) {
return patient[0].roomNumber;
});
Ini berfungsi dengan baik, tetapi bagaimana saya melanjutkan sehingga 'John' dan 'Lisa' akan diurutkan dengan benar?
sumber
[0]
pengindeks diperlukan karena dalam contoh asli,patients
adalah array dari array. Ini juga mengapa "solusi yang lebih sederhana" di entri blog yang disebutkan di komentar lain tidak berfungsi di sini.Berikut adalah trik hacky yang terkadang saya gunakan dalam kasus ini: gabungkan properti sedemikian rupa sehingga hasilnya dapat diurutkan:
Namun, seperti yang saya katakan, itu cukup hacky. Untuk melakukan ini dengan benar Anda mungkin ingin benar-benar menggunakan inti JavaScript
sort
metode :Tentu saja, ini akan mengurutkan array Anda pada tempatnya. Jika Anda ingin salinan yang diurutkan (seperti yang
_.sortBy
akan Anda berikan), klon larik terlebih dahulu:Karena bosan, saya baru saja menulis solusi umum (untuk mengurutkan berdasarkan jumlah kunci yang berubah-ubah) untuk ini juga: lihatlah .
sumber
return [patient[0].roomNumber, patient[0].name];
cukup tanpa itujoin
?compare
menangani nilai yang bukan nilai primitif -undefined
,null
atau objek biasa?Saya tahu saya terlambat ke pesta, tetapi saya ingin menambahkan ini untuk mereka yang membutuhkan solusi yang lebih bersih dan lebih cepat yang telah disarankan. Anda dapat menyambung panggilan sortBy dalam urutan dari properti yang paling tidak penting ke properti yang paling penting. Dalam kode di bawah ini saya membuat array baru pasien yang diurutkan berdasarkan Nama dalam RoomNumber dari array asli yang disebut pasien .
sumber
Btw penginisialisasi Anda untuk pasien agak aneh, bukan? mengapa Anda tidak menginisialisasi variabel ini sebagai ini -sebagai array objek yang sebenarnya -Anda dapat melakukannya menggunakan _.flatten () dan bukan sebagai array array objek tunggal, mungkin itu masalah kesalahan ketik):
Aku mengurutkan daftar itu secara berbeda dan menambahkan Kiko ke tempat tidur Lisa; hanya untuk bersenang-senang dan lihat perubahan apa yang akan dilakukan ...
periksa diurutkan dan Anda akan melihat ini
jadi jawaban saya adalah: gunakan array dalam fungsi panggilan balik Anda ini sangat mirip dengan jawaban Dan Tao , saya hanya lupa bergabung (mungkin karena saya menghapus array array item unik :))
Menggunakan struktur data Anda, maka itu akan menjadi :
dan testload akan menarik ...
sumber
Tak satu pun dari jawaban ini yang ideal sebagai metode tujuan umum untuk menggunakan beberapa bidang dalam satu urutan. Semua pendekatan di atas tidak efisien karena memerlukan pengurutan beberapa kali (yang, pada daftar yang cukup besar dapat memperlambat banyak hal) atau menghasilkan sejumlah besar objek sampah yang perlu dibersihkan oleh VM (dan pada akhirnya memperlambat program down).
Berikut adalah solusi yang cepat, efisien, dengan mudah memungkinkan pengurutan terbalik, dan dapat digunakan dengan
underscore
ataulodash
, atau langsung denganArray.sort
Bagian terpenting adalah
compositeComparator
metode, yang mengambil larik fungsi pembanding dan mengembalikan fungsi komparator komposit baru.Anda juga memerlukan fungsi pembanding untuk membandingkan bidang yang ingin Anda sortir. The
naturalSort
fungsi akan membuat pembanding diberi bidang tertentu. Menulis pembanding untuk pengurutan terbalik juga sepele.(Semua kode sejauh ini dapat digunakan kembali dan dapat disimpan dalam modul utilitas, misalnya)
Selanjutnya, Anda perlu membuat komparator komposit. Untuk contoh kita, akan terlihat seperti ini:
Ini akan mengurutkan berdasarkan nomor kamar, diikuti dengan nama. Menambahkan kriteria pengurutan tambahan itu mudah dan tidak memengaruhi kinerja pengurutan.
Mengembalikan yang berikut
Alasan saya lebih suka metode ini adalah karena metode ini memungkinkan pengurutan cepat pada jumlah bidang yang berubah-ubah, tidak menghasilkan banyak sampah atau melakukan penggabungan string di dalam pengurutan dan dapat dengan mudah digunakan sehingga beberapa kolom diurutkan terbalik sementara kolom urutan menggunakan alami menyortir.
sumber
Contoh Sederhana dari http://janetriley.net/2014/12/sort-on-multiple-keys-with-underscores-sortby.html (milik @MikeDevenney)
Kode
Dengan Data Anda
sumber
Mungkin underscore.js atau hanya mesin Javascript yang berbeda sekarang dibandingkan saat jawaban ini ditulis, tetapi saya dapat menyelesaikannya hanya dengan mengembalikan array kunci sortir.
Beraksi, silakan lihat biola ini: https://jsfiddle.net/mikeular/xenu3u91/
sumber
Cukup kembalikan larik properti yang ingin Anda urutkan:
Sintaks ES6
Sintaks ES5
Ini tidak memiliki efek samping apa pun untuk mengubah angka menjadi string.
sumber
Anda dapat menggabungkan properti yang ingin Anda urutkan di iterator:
atau sesuatu yang setara.
CATATAN: Karena Anda mengubah atribut numerik roomNumber menjadi string, Anda harus melakukan sesuatu jika Anda memiliki nomor ruangan> 10. Jika tidak, 11 akan muncul sebelum 2. Anda dapat mengisi dengan nol di depan untuk menyelesaikan masalah, yaitu 01 daripada 1.
sumber
Saya pikir Anda lebih baik menggunakan
_.orderBy
daripadasortBy
:sumber
_.orderBy
berfungsi, tetapi ini adalah metode pustaka lodash, bukan garis bawah: lodash.com/docs/4.17.4#orderBy lodash sebagian besar merupakan pengganti drop-in untuk garis bawah, jadi mungkin cocok untuk OP.Jika Anda kebetulan menggunakan Angular, Anda dapat menggunakan filter nomornya di file html daripada menambahkan penangan JS atau CSS. Sebagai contoh:
Dalam contoh itu, jika val = 1234567, itu akan ditampilkan sebagai
Contoh dan panduan lebih lanjut di: https://docs.angularjs.org/api/ng/filter/number
sumber