Có một strcmp JavaScript ()?


127

Bất cứ ai có thể xác minh điều này cho tôi? JavaScript không có phiên bản strcmp (), vì vậy bạn phải viết ra một cái gì đó như:

 ( str1 < str2 ) ? 
            -1 : 
             ( str1 > str2 ? 1 : 0 );

Bạn không đơn độc - những người khác đã làm điều này trước đây . Các PHP.JS dự án thực sự đã làm điều này cho nhiều chức năng thông thường khác, là tốt. Đó là một tài nguyên tiện dụng.
Sậy Copsey

Câu trả lời:


134

Thế còn

str1.localeCompare(str2)

localeCompare () có vẻ tốt, nhưng có vẻ như nó chỉ dành cho MS hoặc không đạt tiêu chuẩn.

10
bạn đang nhìn vào tiêu chuẩn nào? nó dường như nằm trong phần tiêu chuẩn ECMA-262 15.5.4.9, cũng như trong tài liệu tham khảo Javascript của mozilla ( developer.mozilla.org/en/Core_JavaScript_1.5_Reference/
tựa

newacct là hoàn toàn chính xác. Đây dường như là tiêu chuẩn ECMAScript. Có lẽ là giải pháp tốt nhất trong trường hợp này.
coderjoe

3
localeCompare()đôi khi hành xử khác nhau trên mỗi trình duyệt.
Varda Elentári

1
@ VardaElentári: Chỉ dành cho các nhân vật không có thứ tự từ vựng trong ngôn ngữ đã cho. Đối với các ký tự làm và trình duyệt không hạn chế phần nào họ sử dụng Unicode, kết quả phù hợp và được xác định bởi ECMA-402 và Unicode .
TJ Crowder

38

Javascript không có nó, như bạn chỉ ra.

Một tìm kiếm nhanh đã đưa ra:

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

từ http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_strcmp/

Tất nhiên, bạn chỉ có thể thêm localeCompare nếu cần:

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

Và sử dụng str1.localeCompare(str2)ở mọi nơi mà không phải lo lắng về trình duyệt cục bộ đã được cung cấp cùng với nó. Vấn đề duy nhất là bạn sẽ phải thêm hỗ trợ localesoptions nếu bạn quan tâm đến điều đó.


Tôi nghĩ rằng đây là một cách xử lý tốt (phát hiện tính năng và polyfill FTW), nhưng nếu hiệu suất tốc độ vi mô rất quan trọng, vì sự cần thiết của phương pháp này, thì tôi hơi bối rối khi ==sử dụng và không ===tránh khỏi điều sau chuyển đổi loại và do đó là micro thứ hai nhanh hơn.
Tokimon

một lưu ý về polyfill-- localeCompare không phân biệt chữ hoa chữ thường, vì vậy để làm cho polyfill cũng không phân biệt chữ hoa chữ thường, bạn có thể làm một cái gì đó như- var a = this.toUpperCase(); var b = str.toUpperCase(); return ((a == b) ? 0 : ((a > b) ? 1 : -1));
Kip

22

localeCompare()chậm , vì vậy nếu bạn không quan tâm đến thứ tự "chính xác" của các chuỗi ký tự không phải tiếng Anh, hãy thử phương pháp ban đầu của bạn hoặc tìm kiếm rõ ràng hơn:

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

Đây là một thứ tự cường độ nhanh hơn localeCompare()trên máy của tôi.

Việc +đảm bảo rằng câu trả lời luôn luôn là số chứ không phải boolean.


Hai lỗi: không trả về 0 cho str1 == str2, không trả về 1 cho str1> str2
stackunderflow

2
@stackunderflow Tôi đang sử dụng nó thành công trong chức năng sắp xếp. Lỗi mà bạn đang gặp phải là gì?
1 ''

1
Điều này sẽ trả về -1, false hoặc true thay vì -1, 0 hoặc 1. Để luôn luôn trả về số, hãy chỉnh nó như thế này: str1 <str2? -1: + (str1> str2)
jfren484

2
Một điều nữa (tôi đang sử dụng mã này trong mã tôi đang viết ngay bây giờ, vì vậy tôi đã hoàn thiện nó): chỉ cần lưu ý rằng đây là so sánh phân biệt chữ hoa chữ thường ('Foo' sẽ đến trước 'bar' nhưng ' Thanh 'sẽ đến sau' foo '). Điều đó tương ứng với câu hỏi của OP về strcmp, nhưng nhiều người có thể đến đây để tìm kiếm một so sánh không rõ ràng.
jfren484

5
Đây là một biểu hiện thậm chí trông gọn gàng hơn:(str1 > str2) - (str1 < str2)
Jonathan Gilbert

2
var strcmp = new Intl.Collator(undefined, {numeric:true, sensitivity:'base'}).compare;

Sử dụng: strcmp(string1, string2)

Kết quả: 1có nghĩa là chuỗi1 lớn hơn, 0có nghĩa là bằng nhau, -1có nghĩa là chuỗi2 lớn hơn.

Điều này có hiệu suất cao hơn String.prototype.localeCompare

Ngoài ra, numeric:truelàm cho nó làm so sánh số logic



-1

Làm thế nào về:

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

Sau đó, để so sánh s1 với 2:

s1.strcmp(s2)

1
Nó sẽ giúp ích nếu bạn nói tại sao họ không nên làm những gì họ đã làm. Tôi có thể hiểu nếu họ đang thay đổi cách một phương thức chức năng hiện có hoạt động, nhưng trong trường hợp này họ đang thêm một phương thức mới.
Thư giãn tại Síp

2
Mở rộng các nguyên mẫu vô điều kiện như thế này nói chung là không lớn.
Christopher
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.