Apakah ada JavaScript strcmp ()?


Jawaban:


134

Bagaimana dengan

str1.localeCompare(str2)

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.


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.


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



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

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