Сравнение строк в JavaScript традиционно выполняется через
лексикографический порядок Unicode, однако такой подход не учитывает
языковые правила, особенности регистра, ударений и числовых фрагментов
внутри текста. Для корректной локализации используется объект
Intl.Collator, предоставляющий гибкие опции управления
сравнением строк.
Главная идея коллатора заключается в том, что результат сравнения зависит не только от символов, но и от выбранной локали и набора правил сортировки.
const collator = new Intl.Collator('ru');
collator.compare('яблоко', 'банан');
Метод compare возвращает:
sensitivity определяет, какие различия между символами
считаются значимыми при сравнении.
Доступные значения:
baseСравнение игнорирует диакритику и регистр.
new Intl.Collator('ru', { sensitivity: 'base' });
Примеры:
a = Ae = éИспользуется для грубой сортировки без учета тонких различий.
accentУчитываются различия в диакритических знаках, но игнорируется регистр.
new Intl.Collator('fr', { sensitivity: 'accent' });
Примеры:
e ≠ éa = AПодходит для языков, где ударения изменяют смысл слова.
caseУчитывается регистр, но игнорируются диакритические знаки.
new Intl.Collator('en', { sensitivity: 'case' });
Примеры:
a ≠ Ae = évariantНаиболее строгий режим сравнения.
new Intl.Collator('de', { sensitivity: 'variant' });
Примеры:
a ≠ Aa ≠ äИспользуется для точной сортировки без нормализации.
numeric включает числовое сравнение внутри строк. Без
этой опции строки сортируются лексикографически, что приводит к
неожиданным результатам:
['2', '10', '1'].sort();
// ['1', '10', '2']
С включённым numeric:
new Intl.Collator('en', { numeric: true }).compare('2', '10');
Результат сортировки:
['1', '2', '10']
Особенности:
"file2" и
"file10"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 позволяет игнорировать знаки
препинания при сравнении строк.
new Intl.Collator('en', { ignorePunctuation: true });
Примеры влияния:
"hello-world" и "helloworld" считаются
эквивалентными"a,b" и "ab" могут сортироваться
одинаковоИспользуется при обработке текстов, где пунктуация не несёт смысловой нагрузки.
usage определяет назначение коллатора:
sortИспользуется для сортировки массивов строк.
new Intl.Collator('ru', { usage: 'sort' });
Оптимизирован для обработки больших наборов данных.
searchИспользуется для сравнения строк при поиске совпадений.
new Intl.Collator('ru', { usage: 'search' });
Особенности:
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 можно использовать напрямую в
сортировке:
const collator = new Intl.Collator('ru');
['яблоко', 'банан', 'груша'].sort(collator.compare);
Важно учитывать:
Intl.Collator создаётся один раз и
переиспользуетсяsort снижает
производительностьРазные языки используют различные правила сортировки:
ä, ö,
ü)new Intl.Collator('de');
new Intl.Collator('fr');
new Intl.Collator('ja');
new Intl.Collator('zh');
Локаль влияет не только на порядок, но и на интерпретацию символов.
Сравнение строк зависит от нормализации 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 может вести себя по-разному при сложных строках
с несколькими числами