Опции сравнения строк

Сравнение строк в JavaScript традиционно выполняется через лексикографический порядок Unicode, однако такой подход не учитывает языковые правила, особенности регистра, ударений и числовых фрагментов внутри текста. Для корректной локализации используется объект Intl.Collator, предоставляющий гибкие опции управления сравнением строк.

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

const collator = new Intl.Collator('ru');
collator.compare('яблоко', 'банан');

Метод compare возвращает:

  • отрицательное число, если первая строка меньше второй
  • положительное число, если первая больше второй
  • 0, если строки эквивалентны

Опция sensitivity

sensitivity определяет, какие различия между символами считаются значимыми при сравнении.

Доступные значения:

base

Сравнение игнорирует диакритику и регистр.

new Intl.Collator('ru', { sensitivity: 'base' });

Примеры:

  • a = A
  • e = é

Используется для грубой сортировки без учета тонких различий.


accent

Учитываются различия в диакритических знаках, но игнорируется регистр.

new Intl.Collator('fr', { sensitivity: 'accent' });

Примеры:

  • eé
  • a = A

Подходит для языков, где ударения изменяют смысл слова.


case

Учитывается регистр, но игнорируются диакритические знаки.

new Intl.Collator('en', { sensitivity: 'case' });

Примеры:

  • aA
  • e = é

variant

Наиболее строгий режим сравнения.

new Intl.Collator('de', { sensitivity: 'variant' });

Примеры:

  • aA
  • aä

Используется для точной сортировки без нормализации.


Опция numeric

numeric включает числовое сравнение внутри строк. Без этой опции строки сортируются лексикографически, что приводит к неожиданным результатам:

['2', '10', '1'].sort();
// ['1', '10', '2']

С включённым numeric:

new Intl.Collator('en', { numeric: true }).compare('2', '10');

Результат сортировки:

['1', '2', '10']

Особенности:

  • распознаёт числа внутри строк
  • работает с составными значениями: "file2" и "file10"
  • полезно для сортировки файлов, версий, списков

Опция caseFirst

caseFirst управляет приоритетом регистра при сортировке.

Возможные значения:

upper

Сначала идут строки с заглавными буквами.

new Intl.Collator('en', { caseFirst: 'upper' });

Результат:

A
a
B
b

lower

Сначала идут строки со строчными буквами.

new Intl.Collator('en', { caseFirst: 'lower' });

Результат:

a
A
b
B

false

Регистр не влияет на порядок.

new Intl.Collator('en', { caseFirst: false });

Опция ignorePunctuation

ignorePunctuation позволяет игнорировать знаки препинания при сравнении строк.

new Intl.Collator('en', { ignorePunctuation: true });

Примеры влияния:

  • "hello-world" и "helloworld" считаются эквивалентными
  • "a,b" и "ab" могут сортироваться одинаково

Используется при обработке текстов, где пунктуация не несёт смысловой нагрузки.


Опция usage

usage определяет назначение коллатора:

sort

Используется для сортировки массивов строк.

new Intl.Collator('ru', { usage: 'sort' });

Оптимизирован для обработки больших наборов данных.


Используется для сравнения строк при поиске совпадений.

new Intl.Collator('ru', { usage: 'search' });

Особенности:

  • более строгая нормализация
  • повышенная точность совпадений
  • учитывает особенности языковой близости символов

Опция localeMatcher

localeMatcher определяет стратегию подбора локали:

best fit

Пытается подобрать наиболее подходящую локаль.

new Intl.Collator('ru-KZ', { localeMatcher: 'best fit' });

lookup

Строгое соответствие стандарту BCP 47.

new Intl.Collator('ru-KZ', { localeMatcher: 'lookup' });

Разница проявляется при работе с редкими или составными локалями.


Комбинации опций

Intl.Collator позволяет комбинировать параметры для точной настройки поведения сравнения.

const collator = new Intl.Collator('en', {
  sensitivity: 'base',
  numeric: true,
  caseFirst: 'upper',
  ignorePunctuation: true
});

Такой набор обеспечивает:

  • игнорирование регистра и диакритики
  • корректную обработку чисел
  • приоритет заглавных букв
  • игнорирование пунктуации

Поведение compare и оптимизация

Метод compare можно использовать напрямую в сортировке:

const collator = new Intl.Collator('ru');

['яблоко', 'банан', 'груша'].sort(collator.compare);

Важно учитывать:

  • Intl.Collator создаётся один раз и переиспользуется
  • повторное создание коллатора внутри sort снижает производительность
  • сравнение оптимизировано на уровне движка JavaScript

Поведение в разных локалях

Разные языки используют различные правила сортировки:

  • немецкий учитывает умляуты (ä, ö, ü)
  • французский чувствителен к диакритике
  • японский использует силлабическую сортировку
  • китайский зависит от радикалов и фонетики
new Intl.Collator('de');
new Intl.Collator('fr');
new Intl.Collator('ja');
new Intl.Collator('zh');

Локаль влияет не только на порядок, но и на интерпретацию символов.


Влияние Unicode-нормализации

Сравнение строк зависит от нормализации Unicode. Символы могут иметь несколько представлений:

  • é как один символ
  • e + комбинирующий акцент

Intl.Collator учитывает эти особенности и приводит строки к сопоставимому виду перед сравнением.


Использование в реальных структурах данных

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

  • бинарный поиск по отсортированным строкам
  • индексация текстовых данных
  • фильтрация результатов поиска
  • группировка строк по языковым правилам
const collator = new Intl.Collator('ru', { sensitivity: 'base' });

function contains(arr, value) {
  return arr.find(item => collator.compare(item, value) === 0);
}

Ограничения и особенности поведения

Некоторые особенности требуют внимания:

  • результаты сравнения зависят от реализации движка
  • не все комбинации опций одинаково поддерживаются в разных средах
  • numeric может вести себя по-разному при сложных строках с несколькими числами
  • производительность зависит от длины строк и количества сравнений