Перейти к содержимому
Теория · Строки · урок 8 из 12

Сравнение строк

Как найти слово в бумажном словаре? Сначала смотрят на первую букву. Если первые буквы совпали, сравнивают вторые, потом третьи, пока буквы не разойдутся.

JavaScript сравнивает строки так же, буква за буквой. Только его «алфавит» другой, и операторы < и > иногда дают неожиданный порядок. Заглавная Z оказывается раньше строчной a, а строка "10" — меньше строки "9":

JavaScript
console.log("apple" < "banana"); // true
console.log("Zebra" < "apple"); // true
console.log("10" < "9"); // true
console.log("10" < 9); // false

Разберём вывод по строкам:

  1. "apple" < "banana" даёт true, как в словаре.
  2. "Zebra" < "apple" тоже даёт true, хотя в словаре apple стоит раньше.
  3. "10" < "9" даёт true, хотя десять больше девяти.
  4. "10" < 9 даёт false: справа число, и сравнение идёт по-другому.

Давайте выясним, откуда берётся такой порядок.

Посимвольно по кодам

У каждого символа есть числовой код символа. Метод charCodeAt(i) возвращает код символа с индексом i. Коды идут такими группами:

  • у цифр — от 48 до 57;
  • у заглавных латинских букв — от 65 до 90;
  • у строчных латинских букв — от 97 до 122.
JavaScript
console.log("A".charCodeAt(0), "Z".charCodeAt(0), "a".charCodeAt(0)); // 65 90 97
console.log("1".charCodeAt(0), "9".charCodeAt(0)); // 49 57
console.log("app" < "apple", "Ann" === "ann"); // true false

Это и есть «алфавит» JavaScript: все заглавные латинские буквы идут раньше всех строчных. В словаре Z и z стоят рядом, и здесь аналогия со словарём перестаёт работать.

Две строки сравниваются посимвольно, слева направо:

  1. Пока символы совпадают, JavaScript идёт дальше.
  2. На первом различии меньше та строка, у которой код символа меньше; остальные символы уже не важны.
  3. Если одна строка кончилась раньше и совпадает с началом другой, она меньше: "app" < "apple".

Виджет ниже проходит эти шаги в функции isLess с циклом while. Нажимайте «Следующий шаг» и следите за счётчиком i и кодами ca и cb: ответ появляется на первом различии.

ВживуюКак < сравнивает строкишаг 1 из 13 · рамок: 1

Скрипт вызывает isLess("10", "9") и ждёт ответ.

Коды сравниваются слева направо до первого различия

Отсюда "10" < "9" даёт true: первые символы "1" и "9" разные, а код "1" меньше.

Если с одной стороны число, строка превращается в число, как при ==, и "10" < 9 сравнивает 10 с 9.

Оператор === для строк проверяет, что символы и их порядок совпадают полностью, с учётом регистра. Поэтому "Ann" === "ann" даёт false.

Этот вопрос часто задают на собеседовании: «Почему "10" < "9" даёт true?» Ответ состоит из двух частей:

  • обе стороны — строки, поэтому они сравниваются посимвольно по кодам;
  • код "1" меньше кода "9", и дальше сравнение не идёт.

Порядок по алфавиту

Метод a.localeCompare(b) сравнивает строки по правилам языка и возвращает:

  • отрицательное число, если a идёт раньше b;
  • положительное число, если a идёт позже;
  • ноль для равных строк.

Язык и его правила называют локалью. Её код передают вторым аргументом: "ru", "en".

JavaScript
console.log("Zebra".localeCompare("apple") < 0); // false
console.log("apple".localeCompare("Zebra", "en") < 0); // true
console.log("apple".localeCompare("apple")); // 0

В отличие от <, localeCompare ставит "Zebra" после "apple", как в словаре. Кириллица тоже сравнивается по кодам, и у буквы ё код больше, чем у я. Поэтому "ёж" < "яма" даёт false, а "ёж".localeCompare("яма", "ru") возвращает отрицательное число: по алфавиту ё стоит рядом с е.

Частая ошибка

Числа, прочитанные из текста, сравнили как строки:

JavaScript
const a = "100";
const b = "25";
console.log(a > b); // ✗

Программа печатает false, хотя 100 больше 25. Обе стороны — строки, и сравнение остановилось на первом символе: "1" меньше "2". Превратите строки в числа перед сравнением: Number(a) > Number(b) даёт true.

Главное

  • < и > сравнивают строки посимвольно по кодам символов, и решает первое различие.
  • Поэтому "Zebra" < "apple" и "10" < "9" дают true, а начало строки меньше всей строки.
  • Если с одной стороны число, строка превращается в число.
  • Для порядка по алфавиту берут localeCompare, а числа из текста сравнивают после Number.

Подпишись, чтобы пройти курс

Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.

Войти другим способом