Saya memiliki daftar objek yang ingin saya urutkan berdasarkan bidang attr
string tipe. Saya mencoba menggunakan-
list.sort(function (a, b) {
return a.attr - b.attr
})
tetapi ternyata itu -
tidak berfungsi dengan string dalam JavaScript. Bagaimana saya bisa mengurutkan daftar objek berdasarkan atribut dengan tipe string?
javascript
string
airportyh
sumber
sumber
JavaScript case insensitive string comparison
di stackoverflow.com/questions/2140627/…Javascript : remove accents/diacritics in strings
di stackoverflow.com/questions/990904/…Jawaban:
Gunakan
String.prototype.localeCompare
per contoh Anda:Kami memaksa a.attr menjadi string untuk menghindari pengecualian.
localeCompare
telah didukung sejak Internet Explorer 6 dan Firefox 1. Anda juga dapat melihat kode berikut yang digunakan yang tidak menghormati lokal:sumber
localeCompare()
tidak mengalami masalah ini tetapi tidak memahami angka sehingga Anda akan mendapatkan ["1", "10", "2"] seperti halnya dengan menyortir perbandingan dalam sebagian besar bahasa. jika Anda ingin mengurutkan untuk ujung depan UI Anda, lihat ke dalam algoritma alfanumerik / alamiah stackoverflow.com/questions/4340227/… atau stackoverflow.com/questions/4321829/…localeCompare()
hanya didukung di peramban modern: IE11 + pada saat penulisan, lihat developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…localeCompare()
banyak versi yang kembali, tetapi tidak mendukung menentukan lokal sampai versi 11. Perhatikan juga pertanyaan-pertanyaan yang terkait dengan Dead.Rabit.Jawaban yang diperbarui (Oktober 2014)
Saya benar-benar kesal tentang urutan penyortiran alami string ini sehingga saya mengambil cukup waktu untuk menyelidiki masalah ini. Saya harap ini membantu.
Singkat cerita
localeCompare()
dukungan karakter adalah badass, gunakan saja. Seperti yang ditunjukkan olehShog9
, jawaban untuk pertanyaan Anda adalah:Bug yang ditemukan di semua implementasi "natural sort sort order" javascript khusus
Ada cukup banyak implementasi khusus di luar sana, mencoba melakukan perbandingan string yang lebih tepat disebut "urutan pengurutan string natural"
Ketika "bermain" dengan implementasi ini, saya selalu memperhatikan beberapa pilihan "natural sorting order" yang aneh, atau lebih tepatnya kesalahan (atau kelalaian dalam kasus terbaik).
Biasanya, karakter khusus (spasi, tanda hubung, tanda bintang, tanda kurung, dan sebagainya) tidak diproses dengan benar.
Anda kemudian akan menemukan mereka muncul bercampur di tempat yang berbeda, biasanya itu bisa:
Ketika seseorang akan mengharapkan karakter khusus untuk semua "dikelompokkan" bersama di satu tempat, kecuali untuk karakter khusus ruang mungkin (yang akan selalu menjadi karakter pertama). Yaitu, baik semua sebelum angka, atau semua antara angka dan huruf (huruf kecil & besar menjadi "bersama" satu demi satu), atau semua setelah huruf.
Kesimpulan saya adalah mereka semua gagal memberikan urutan yang konsisten ketika saya mulai menambahkan karakter yang hampir tidak biasa (mis. Karakter dengan diakritik atau karakter seperti tanda hubung, tanda seru, dan sebagainya).
Penelitian tentang implementasi kustom:
Natural Compare Lite
https://github.com/litejs/natural-compare-lite : Gagal menyortir secara konsisten https://github.com/litejs/natural-compare-lite/issues/1 dan http://jsbin.com/bevututodavi/ 1 / edit? Js, konsol , penyortiran karakter latin dasar http://jsbin.com/bevututodavi/5/edit?js,consoleNatural Sort
https://github.com/javve/natural-sort : Gagal menyortir secara konsisten, lihat masalah https://github.com/javve/natural-sort/issues/7 dan lihat karakter latin dasar menyortir http: // jsbin. com / cipimosedoqe / 3 / edit? js, consoleJavascript Natural Sort
https://github.com/overset/javascript-natural-sort : tampaknya agak diabaikan sejak Februari 2012, gagal menyortir secara konsisten, lihat masalah https://github.com/overset/javascript-natural-sort/issues/16Alphanum
http://www.davekoelle.com/files/alphanum.js , Gagal menyortir secara konsisten, lihat http://jsbin.com/tuminoxifuyo/1/edit?js,consoleImplementasi asli "Urutan string alami" browser via
localeCompare()
localeCompare()
implementasi terlama (tanpa argumen lokal dan opsi) didukung oleh IE6 +, lihat http://msdn.microsoft.com/en-us/library/ie/s4esdbwz(v=vs.94).aspx (gulir ke bawah ke localeCompare ( ) metode). Built-inlocaleCompare()
metode melakukan pekerjaan yang jauh lebih baik di menyortir, bahkan karakter internasional & khusus. Satu-satunya masalah menggunakanlocaleCompare()
metode ini adalah "urutan lokal dan urutan yang digunakan sepenuhnya tergantung pada implementasi". Dengan kata lain, saat menggunakan localeCompare seperti stringOne.localeCompare (stringTwo): Firefox, Safari, Chrome & IE memiliki urutan pengurutan berbeda untuk Strings.Penelitian tentang implementasi browser-asli:
Kesulitan "urutan penyortiran alami string"
Menerapkan algoritma yang solid (artinya: konsisten tetapi juga mencakup berbagai karakter) adalah tugas yang sangat sulit. UTF8 berisi lebih dari 2000 karakter & mencakup lebih dari 120 skrip (bahasa) . Akhirnya, ada beberapa spesifikasi untuk tugas ini, itu disebut "Unicode Collation Algorithm", yang dapat ditemukan di http://www.unicode.org/reports/tr10/ . Anda dapat menemukan informasi lebih lanjut tentang ini pada pertanyaan ini yang saya posting /software/257286/is-there-any-language-agnostic-specification-for-string-natural-sorting-order
Kesimpulan akhir
Jadi, mengingat tingkat dukungan saat ini yang diberikan oleh implementasi kustom javascript yang saya temui, kita mungkin tidak akan pernah melihat apa pun yang mendekati mendukung semua karakter & skrip (bahasa) ini. Oleh karena itu saya lebih suka menggunakan metode localeCompare () asli browser. Ya, ia memang memiliki kelemahan karena tidak konsisten di seluruh peramban, tetapi pengujian dasar menunjukkan bahwa ia mencakup jangkauan karakter yang jauh lebih luas, memungkinkan pesanan sortir yang padat & bermakna.
Jadi seperti yang ditunjukkan
Shog9
, jawaban untuk pertanyaan Anda adalah:Bacaan lebih lanjut:
Berkat jawaban bagus Shog9, yang membuat saya ke arah yang "benar", saya percaya
sumber
Jawab (dalam ECMAScript Modern)
Atau
Deskripsi
Casting nilai boolean ke angka menghasilkan yang berikut:
true
->1
false
->0
Pertimbangkan tiga pola yang mungkin:
(x > y) - (y < x)
->1 - 0
->1
(x > y) - (y < x)
->0 - 0
->0
(x > y) - (y < x)
->0 - 1
->-1
(Alternatif)
+(x > y) || -(x < y)
->1 || 0
->1
+(x > y) || -(x < y)
->0 || 0
->0
+(x > y) || -(x < y)
->0 || -1
->-1
Jadi logika ini setara dengan fungsi pembanding sortir tipikal.
sumber
localeCompare
dan perbandingan standar menghasilkan hasil yang berbeda. Mana yang kamu harapkan["A", "b", "C", "d"].sort((a, b) => a.localeCompare(b))
macam dalam urutan alfabet case-insensitive sementara["A", "b", "C", "d"].sort((a, b) => (a > b) - (a < b))
tidak dalam urutan codepointAnda harus menggunakan> atau <dan == di sini. Jadi solusinya adalah:
sumber
Fungsi panah ternary bersarang
sumber
karena string dapat dibandingkan secara langsung dalam javascript, ini akan melakukan pekerjaan
pengurangan dalam fungsi sortir digunakan hanya ketika sort non-abjad (numerik) diinginkan dan tentu saja itu tidak bekerja dengan string
sumber
Saya sudah lama terganggu tentang hal ini, jadi saya akhirnya meneliti ini dan memberi Anda alasan panjang lebar mengapa hal-hal seperti itu adanya.
Dari spec :
Jadi sekarang kita pergi ke 11.9.6
Itu dia. Operator triple sama dengan yang diterapkan pada string mengembalikan true jika argumen benar-benar string yang sama (panjang yang sama dan karakter yang sama di posisi yang sesuai).
Jadi
===
akan berfungsi dalam kasus ketika kami mencoba membandingkan string yang mungkin berasal dari sumber yang berbeda, tetapi yang kami tahu pada akhirnya akan memiliki nilai yang sama - skenario yang cukup umum untuk string sebaris dalam kode kami. Sebagai contoh, jika kita memiliki variabel bernamaconnection_state
, dan kita ingin tahu di mana salah satu dari keadaan berikut['connecting', 'connected', 'disconnecting', 'disconnected']
ini sekarang, kita dapat langsung menggunakan===
.Tapi masih ada lagi. Tepat di atas 11.9.4, ada catatan singkat:
Hmm. Apa sekarang? String yang diperoleh secara eksternal dapat, dan kemungkinan besar akan, aneh unik, dan lembut kita
===
tidak akan melakukannya dengan adil. In datanglocaleCompare
untuk menyelamatkan:Kita bisa pulang sekarang.
tl; dr;
Untuk membandingkan string dalam javascript, gunakan
localeCompare
; jika Anda tahu bahwa string tidak memiliki komponen non-ASCII karena mereka, misalnya, konstanta program internal, maka===
juga berfungsi.sumber
Dalam operasi Anda dalam pertanyaan awal Anda, Anda melakukan operasi berikut:
Jadi, dengan asumsi itu adalah angka (yaitu item1.attr = "1", item2.attr = "2") Anda masih dapat menggunakan operator "===" (atau evaluator ketat lainnya) asalkan Anda memastikan tipe. Berikut ini harus bekerja:
Jika mereka alphaNumeric, maka gunakan localCompare ().
sumber
Cara kerja sampel:
sumber
sumber
sumber