Сортировка и поиск с localeCompare
С задачей обычной сортировки, если речь про английский язык или числа, норм справляется
sort() или sort((a, b) => a - b).Но вот когда сортируются «неанглийские» строки, то тогда пригодится метод localeCompare у строк:
sort((a, b) => a.localeCompare(b)), который сравнивает сроки учитывая действующую локаль пользовательской системы. Грубо говоря, где в текущей локали один Unicode-символ находится по сравнению с другим символом – перед ним или после него?Что интересно, базовый метод появился в браузерах ещё практически с начала существования Chrome, Firefox и Safari. Но позже в него была добавлена поддержка дополнительных параметров, уточняющих как именно нужно сравнивать строки. Причём под капотом
localeCompare будет вызывать Intl.Collator API, в браузерах его поддерживающих.Настройка
caseFirst — первыми идёт нижний регистр или верхний:
['Е', 'а', 'е', 'А'].sort((a, b) => a.localeCompare(b, 'ru'))
// по умолчанию сначала нижний регистр
// ["а","А","е","Е"]
['Е', 'а', 'е', 'А'].sort((a, b) => a.localeCompare(b, 'ru', { caseFirst: 'upper' }))
// теперь сначала идёт верхний регистр
// ["А","а","Е","е"]
Это актуально и для английских текстов тоже.
Настройка
sensitivity — учитывать ли при сравнении регистр и вспомогательные символы вокруг буквы (a и á, е и ё):
'лёд'.localeCompare('ЛЕД', 'ru', { sensitivity: 'variant' }) === 0
// л ≠ д, е ≠ ё, л ≠ Л
// false
'лед'.localeCompare('лёд', 'ru', { sensitivity: 'case' }) === 0
// л ≠ д, е = ё, л ≠ Л.
// true
'Лёд'.localeCompare('лёд', 'ru', { sensitivity: 'accent' }) === 0
// л ≠ д, е ≠ ё, л = Л
// true
'лёд'.localeCompare('ЛЕД', 'ru', { sensitivity: 'base' }) === 0
// л ≠ д, е = ё, л = Л
// true
То есть если пользователь вводит в поиск
ЛЕД, можно однозначно определить, что это лёд прямо в браузере.Настройка
numeric — для корректной сортировки строк с числами:
['09', '1', '2', '01', '10'].sort((a, b) => a.localeCompare(b))
// по умолчанию сортируется по символам
// ["01","09","1","10","2"]
['09', '1', '2', '01', '10'].sort((a, b) => a.localeCompare(b, 'ru', { numeric: true }))
// теперь строки учитываются как числа
// ["1","01","2","09","10"]
Так можно отсортировать строки с числами без явного приведения к числам.
Что радует, все возможные доп настройки доступны с Chrome 87, FF 85, Safari 14.1, Node 15.
Демо тут
@web_platform | Поддержать канал 🤝