Есть ли JavaScript strcmp()?

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

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

8 ответов

Как насчет

str1.localeCompare(str2)

У 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 если ты заботишься об этом.

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

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

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

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

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

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

Результат: 1 означает, что string1 больше, 0 означает равный, -1 означает, что string2 больше.

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

Также, numeric:true делает это сравнение логических чисел

Как насчет:

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

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

s1.strcmp(s2)

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

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

Итак, я попал в эту кроличью нору и написал несколько тестов для построения интуиции, результаты странные.tldr похоже, что localeCompare выполняет преобразование в нижний регистр, чего не делают операторы равенства. Это приводит к тому, что «ff» будет >= «ZZ», но сравнение локалей возвращает -1, потому что «ff» <= 'zz'

Для достижения наилучших результатов просмотрите журналы кода в консоли браузера ctrl + shift + i

второй фрагмент скрывает ручные тесты, поэтому вы видите некоторые случайные.

Главная это помогает кому-то

В моих тестах это примерно на 10% быстрее, чем использование пары троичных операторов для одного и того же набора случайно выбранных слов.

      function strcmp( a, b ) {
    for( let i=0 ; i<Math.min( a.length, b.length ) ; i++ ) {
        const n = a.charCodeAt(i) - b.charCodeAt(i);
        if( n ) return  n && ( ( n>>31 ) || 1 );
    }
    const n = a.length - b.length;
    return  n && ( ( n>>31 ) || 1 );
}
Другие вопросы по тегам