Apakah ada JavaScript strcmp ()?

127

Adakah yang bisa memverifikasi ini untuk saya? JavaScript tidak memiliki versi strcmp (), jadi Anda harus menulis sesuatu seperti:

 ( str1 < str2 ) ? 
            -1 : 
             ( str1 > str2 ? 1 : 0 );
Karel Bílek
sumber
Anda tidak sendirian - orang lain pernah melakukan ini sebelumnya . Proyek PHP.JS sebenarnya telah melakukan ini untuk banyak fungsi umum lainnya, juga. Ini sumber yang berguna.
Reed Copsey

Jawaban:

134

Bagaimana dengan

str1.localeCompare(str2)
berita baru
sumber
localeCompare () terlihat bagus, tetapi sepertinya hanya MS, atau tidak dalam standar terbaik.
10
standar apa yang Anda lihat? tampaknya di ECMA-262 bagian standar 15.5.4.9, serta dalam referensi Javascript mozilla ( developer.mozilla.org/en/Core_JavaScript_1.5_Reference/… )
newacct
Newacct benar-benar benar. Ini tampaknya menjadi standar ECMAScript. Mungkin solusi terbaik dalam hal ini.
coderjoe
3
localeCompare()terkadang berperilaku berbeda di setiap browser.
Varda Elentári
1
@ VardaElentári: Hanya untuk karakter yang tidak memiliki urutan leksikal di lokal yang diberikan. Untuk karakter yang melakukan dan browser yang tidak membatasi bagian apa dari Unicode yang mereka gunakan, hasilnya konsisten dan didefinisikan oleh ECMA-402 dan Unicode .
TJ Crowder
38

Javascript tidak memilikinya, seperti yang Anda tunjukkan.

Pencarian cepat muncul dengan:

function strcmp ( str1, str2 ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Waldo Malqui Silva
    // +      input by: Steve Hilder
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +    revised by: gorthaur
    // *     example 1: strcmp( 'waldo', 'owald' );
    // *     returns 1: 1
    // *     example 2: strcmp( 'owald', 'waldo' );
    // *     returns 2: -1

    return ( ( str1 == str2 ) ? 0 : ( ( str1 > str2 ) ? 1 : -1 ) );
}

dari http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_strcmp/

Tentu saja, Anda bisa menambahkan localeCompare jika diperlukan:

if (typeof(String.prototype.localeCompare) === 'undefined') {
    String.prototype.localeCompare = function(str, locale, options) {
        return ((this == str) ? 0 : ((this > str) ? 1 : -1));
    };
}

Dan gunakan di str1.localeCompare(str2)mana-mana, tanpa harus khawatir apakah browser lokal telah dikirimkan dengannya. Satu-satunya masalah adalah Anda harus menambahkan dukungan untuk localesdanoptions jika Anda peduli tentang itu.

Esteban Küber
sumber
Saya pikir ini adalah cara yang bagus untuk menanganinya (deteksi fitur dan FTW polyfill), tetapi jika kinerja kecepatan mikro sangat penting, seperti untuk kebutuhan metode ini, maka saya sedikit bingung yang ==digunakan dan tidak ===sejak yang terakhir menghindari ketik konversi dan karenanya mikro itu lebih cepat.
Tokimon
catatan pada polyfill - localeCompare tidak peka huruf besar kecil, jadi untuk membuat polyfill juga tidak peka huruf besar kecil, Anda mungkin melakukan sesuatu seperti var a = this.toUpperCase(); var b = str.toUpperCase(); return ((a == b) ? 0 : ((a > b) ? 1 : -1));
Kip
22

localeCompare()lambat , jadi jika Anda tidak peduli dengan urutan "benar" string non-Bahasa Inggris, coba metode asli Anda atau yang tampak bersih:

str1 < str2 ? -1 : +(str1 > str2)

Ini adalah urutan besarnya lebih cepat dari localeCompare()pada mesin saya.

The +memastikan bahwa jawabannya selalu numerik daripada boolean.

1 ''
sumber
Dua bug: tidak mengembalikan 0 untuk str1 == str2, tidak mengembalikan 1 untuk str1> str2
stackunderflow
2
@stackunderflow Saya berhasil menggunakannya dalam fungsi penyortiran. Apa bug yang Anda alami?
1 ''
1
Ini akan mengembalikan -1, false, atau true alih-alih -1, 0, atau 1. Untuk mendapatkannya selalu kembali, atur seperti ini: str1 <str2? -1: + (str1> str2)
jfren484
2
Satu hal lagi (saya menggunakan ini dalam kode yang saya tulis sekarang, jadi saya telah menyempurnakannya): hanya perlu diketahui bahwa ini adalah perbandingan case-sensitive ('Foo' akan datang sebelum 'bar' tapi ' Bar 'akan muncul setelah' foo '). Itu sesuai dengan pertanyaan OP tentang strcmp, tetapi banyak orang mungkin datang ke sini mencari perbandingan kasus-agnostik.
jfren484
5
Inilah ekspresi yang tampak lebih bersih:(str1 > str2) - (str1 < str2)
Jonathan Gilbert
2
var strcmp = new Intl.Collator(undefined, {numeric:true, sensitivity:'base'}).compare;

Pemakaian: strcmp(string1, string2)

Hasil: 1berarti string1 lebih besar, 0berarti sama, -1berarti string2 lebih besar.

Ini memiliki kinerja lebih tinggi daripada String.prototype.localeCompare

Juga, numeric:truemembuatnya melakukan perbandingan angka yang logis

Anonim
sumber
-1

Bagaimana tentang:

String.prototype.strcmp = function(s) {
    if (this < s) return -1;
    if (this > s) return 1;
    return 0;
}

Kemudian, untuk membandingkan s1 dengan 2:

s1.strcmp(s2)
Panos Papadopoulos
sumber
1
Ini akan membantu jika Anda mengatakan mengapa mereka tidak melakukan apa yang mereka lakukan. Saya bisa mengerti jika mereka mengubah bagaimana metode fungsi yang ada bekerja, tetapi dalam kasus ini mereka menambahkan yang baru.
Bersantai Di Siprus
2
Memperluas prototipe tanpa syarat seperti ini umumnya besar tidak-tidak.
Christopher