Есть ли в JavaScript strcmp ()?

127

Кто-нибудь может проверить это для меня? В JavaScript нет версии strcmp (), поэтому вам нужно написать что-то вроде:

 ( str1 < str2 ) ? 
            -1 : 
             ( str1 > str2 ? 1 : 0 );
Карел Билек
источник
Вы не одиноки - это уже делали другие люди . Проект PHP.JS фактически сделал то же самое и для многих других распространенных функций. Это удобный ресурс.
Рид Копси,

Ответы:

134

Что о

str1.localeCompare(str2)
newacct
источник
localeCompare () выглядело хорошо, но похоже, что это было только для MS или в лучшем случае не в стандарте.
10
на какой стандарт вы смотрите? похоже, что он находится в стандартном разделе 15.5.4.9 ECMA-262, а также в справочнике
Mozilla
newacct абсолютно правильный. Кажется, это стандарт ECMAScript. Наверное, лучшее решение в данном случае.
coderjoe
3
localeCompare()иногда ведет себя по-разному в разных браузерах.
Варда Элентари
1
@ VardaElentári: только для символов, которые не имеют лексического порядка в данной локали. Для символов, которые делают и браузеры , которые не ограничивают какие части Unicode они используют, результаты согласуются и определяется ECMA-402 и Unicode .
TJ Crowder
38

Как вы заметили, в Javascript этого нет.

Быстрый поиск дал:

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

из http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_strcmp/

Конечно, при необходимости вы можете просто добавить localeCompare:

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

И используйте str1.localeCompare(str2)везде, не беспокоясь о том, поставляется ли с ним локальный браузер. Единственная проблема заключается в том, что вам придется добавить поддержку, localesиoptions если вам это небезразлично.

Эстебан Кюбер
источник
Я думаю, что это хороший способ справиться с этим (обнаружение функций и полифил FTW), но если производительность на микро-скорости так важна, как для необходимости этого метода, то я немного озадачен, что ==используется, а не ===потому, что последний избегает преобразование типа и, следовательно, на микросекунду быстрее.
Tokimon
примечание по полифилу - localeCompare не чувствителен к регистру, поэтому, чтобы сделать полифил не чувствительным к регистру, вы можете сделать что-то вроде- var a = this.toUpperCase(); var b = str.toUpperCase(); return ((a == b) ? 0 : ((a > b) ? 1 : -1));
Кип
22

localeCompare()работает медленно , поэтому, если вас не волнует "правильный" порядок строк неанглийских символов, попробуйте свой оригинальный метод или более понятный на вид:

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

Это на порядок быстрее, чем localeCompare()на моей машине.

В +гарантирует , что ответ всегда числовой , а не логическое значение.

1 ''
источник
Python
2
@stackunderflow Я успешно использую его в функции сортировки. С какой ошибкой вы столкнулись?
1 ''
1
Это вернет -1, false или true вместо -1, 0 или 1. Чтобы он всегда возвращал числа, настройте его следующим образом: str1 <str2? -1: + (str1> str2)
jfren484
2
Еще одна вещь (я использую это в коде, который пишу прямо сейчас, поэтому я его совершенствовал): просто имейте в виду, что это сравнение с учетом регистра ('Foo' будет стоять перед 'bar', но ' Bar 'будет стоять после' foo '). Это соответствует вопросу OP о strcmp, но многие люди могут прийти сюда в поисках сравнения без учета регистра.
jfren484
5
Вот еще более чистое выражение:(str1 > str2) - (str1 < str2)
Джонатан Гилберт
2
var strcmp = new Intl.Collator(undefined, {numeric:true, sensitivity:'base'}).compare;

Использование: strcmp(string1, string2)

Результат: 1означает, что строка1 больше, 0означает равна, -1означает, что строка2 больше.

Это имеет более высокую производительность, чем String.prototype.localeCompare

Кроме того, numeric:trueделает логическое сравнение чисел

анонимное
источник
Вот некоторые результаты jsperf jsperf.com/localecompare-vs-intl-collator jsperf.com/localecompare-vs-intl-collator
Колин Д.
-1

Как насчет:

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

Затем, чтобы сравнить s1 с 2:

s1.strcmp(s2)
Панос Пападопулос
источник
1
Было бы полезно, если бы вы сказали, почему они не должны делать то, что они сделали. Я мог понять, меняли ли они способ работы существующего метода функции, но в этом случае они добавляют новый.
Relaxing In Cyprus
2
Безоговорочно расширять прототипы подобным образом, как правило, нельзя.
Кристофер