Есть ли в JavaScript функция strcmp()?

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

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

person Community    schedule 24.07.2009    source источник
comment
Вы не одиноки — другие люди делали это раньше. Проект PHP.JS фактически сделал это и для многих других распространенных функций. Это удобный ресурс.   -  person Reed Copsey    schedule 24.07.2009


Ответы (6)


Как насчет

str1.localeCompare(str2)
person newacct    schedule 24.07.2009
comment
localeCompare() выглядел хорошо, но выглядел так, будто он предназначен только для MS или, в лучшем случае, не соответствует стандарту. - person ; 24.07.2009
comment
какой стандарт вы смотрите? похоже, он находится в стандартном разделе ECMA-262 15.5.4.9, а также в справочнике по Javascript Mozilla (developer.mozilla.org/en/Core_JavaScript_1.5_Reference/) - person newacct; 24.07.2009
comment
newacct абсолютно прав. Кажется, это стандарт ECMAScript. Пожалуй, лучшее решение в этом случае. - person coderjoe; 25.07.2009
comment
localeCompare() иногда ведет себя по-разному в разных браузерах. - person Varda Elentári; 23.03.2016
comment
@VardaElentári: только для символов, которые не имеют лексического порядка в данной локали. Для символов, которые делают, и браузеров, которые не ограничивают использование частей Unicode, результаты согласуются и определено ECMA-402 и Unicode. - person T.J. Crowder; 14.04.2017
comment
Обновление 9 лет спустя. Кажется, оно имеет частичную поддержку в IE6+ (охватывающую версию с одним аргументом), полную поддержку в IE11 и, конечно же, поддерживает его во всех других приличных браузерах: caniuse.com/#search=localecompare - person Kip; 13.09.2018

Как вы указываете, в 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, если вас это волнует.

person Esteban Küber    schedule 24.07.2009
comment
Я думаю, что это хороший способ справиться с этим (обнаружение функций и полифилл FTW), но если производительность микроскорости настолько важна, что касается необходимости этого метода, то я немного озадачен тем, что используется ==, а не ===, поскольку последние избегают преобразования типов и, следовательно, быстрее на микросекунду. - person Tokimon; 30.06.2014
comment
примечание о полифиле - localeCompare не чувствителен к регистру, поэтому, чтобы сделать полифилл также нечувствительным к регистру, вы можете сделать что-то вроде - var a = this.toUpperCase(); var b = str.toUpperCase(); return ((a == b) ? 0 : ((a > b) ? 1 : -1)); - person Kip; 13.09.2018

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

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

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

+ гарантирует, что ответ всегда будет числовым, а не логическим.

person 1''    schedule 20.07.2013
comment
Две ошибки: не возвращает 0 для str1 == str2, не возвращает 1 для str1 › str2 - person stackunderflow; 03.09.2013
comment
@stackunderflow Что вы предлагаете вернуть в этих случаях? - person 1''; 03.09.2013
comment
@1 Я полагаю, что это должно быть полезно для сравнения в массиве .prototype.sort, но на самом деле значения не обязательно должны быть 1 и -1, просто отрицательные или положительные, поскольку я только что перечитал стандарт. - person stackunderflow; 03.09.2013
comment
@stackunderflow Я успешно использую его в функции сортировки. Какую ошибку вы испытываете? - person 1''; 03.09.2013
comment
@stackunderflow эта строка верна, она возвращает -1, если str1‹str2, а затем возвращает значение str1>str2, которое от логического до int равно 0 или 1. - person Felype; 13.07.2015
comment
Это вернет -1, false или true вместо -1, 0 или 1. Чтобы он всегда возвращал числа, настройте его следующим образом: str1 ‹ str2 ? -1 : +(стр1 › стр2) - person jfren484; 21.07.2016
comment
Еще одна вещь (я использую это в коде, который пишу прямо сейчас, поэтому я совершенствую его): просто имейте в виду, что это сравнение с учетом регистра («Foo» будет стоять перед «bar», но « «Бар» будет идти после «фу»). Это соответствует вопросу OP о strcmp, но многие люди могут прийти сюда в поисках сравнения без учета регистра. - person jfren484; 21.07.2016
comment
Вот еще более чистое выражение: (str1 > str2) - (str1 < str2) - person Jonathan Gilbert; 15.11.2016

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

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

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

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

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

person Anonymous    schedule 16.01.2019
comment
Вот некоторые результаты jsperf jsperf.com/localecompare-vs-intl-collator jsperf.com/localecompare-vs-intl-collator - person Colin D; 12.03.2020

из этой статьи Как проверить, равны ли две строки в JavaScript:

  1. Как правило, если ваши строки содержат только символы ASCII, вы используете оператор ===, чтобы проверить, равны ли они.
  2. Но когда ваши строки содержат символы, включающие комбинированные символы (например, e + ◌́ = é), вы сначала нормализуете их перед сравнением на равенство следующим образом: s1.normalize() === s2.normalize()
person Runay Dhaygude    schedule 26.05.2021

Как насчет:

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

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

s1.strcmp(s2)
person Panos Papadopoulos    schedule 12.06.2013
comment
Было бы лучше, если бы вы сказали, почему они не должны делать то, что они сделали. Я мог бы понять, если бы они изменили способ работы существующего функционального метода, но в этом случае они добавляют новый. - person Relaxing In Cyprus; 23.06.2014
comment
Безоговорочное расширение прототипов, как это, как правило, недопустимо. - person Christopher; 04.02.2019