Форум программистов, компьютерный форум, киберфорум
mr_dramm
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  

JS String.prototype.localeCompare()

Запись от mr_dramm размещена 02.06.2025 в 18:46
Показов 5688 Комментарии 3
Метки javascript, unicode

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

localeCompare без указания локали для сравнения строк под капотом использует Intl.Collator , который работает согласно Unicode Collation Algorithm (UCA), согласно этому алгоритму происходит нормализация строк с учётом особенностей языка и символов или можно по другому сказать имитация алфовитного порядка, с использованием локали браузера или операционной системы (в зависимости от среды исполнения так как локаль не указана). Для нормализации учитываются веса:
- Первичный вес: Базовый символ (игнорирует диакритики)
- Вторичный вес: Диакритические знаки
- Третичный вес: Регистр букв
В localCompare можно указать дополнительную опцию sensitivity указать какие веса учитывать, по умолчанию учитываются все веса при сравнении.

Веса можно посмотреть в этом файле allkeys.txt
O
Code
1
004F  ; [.252C.0020.0008] # LATIN CAPITAL LETTER O
Ö

Code
1
00D6  ; [.252C.0020.0008][.0000.002B.0002] # LATIN CAPITAL LETTER O WITH DIAERESIS
Z

Code
1
005A  ; [.2682.0020.0008] # LATIN CAPITAL LETTER Z
Из этого видно:
- O и Ö имеют одинаковый первичный вес 252C.
- Ö имеет дополнительный вторичный вес из-за умляута.
- Z имеет более высокий первичный вес 2682.
Поэтому:
JavaScript
1
console.log('Österreich'.localeCompare('Zealand')) // -1
Значит 'Österreich' идёт раньше 'Zealand' в сортировке по UCA.
А вот сравнение через > и < использует коды символов Unicode, без учёта локали и UCA, код символа который можно получить с помощью charCodeAt:

Code
1
2
3
"Ö".charCodeAt(); // 214 
"Z".charCodeAt(); // 90
console.log("Ö" > "Z"); // true
Метки javascript, unicode
Размещено в javascript, unicode
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 3
Комментарии
  1. Старый комментарий
    Аватар для voraa
    Чего то я ничего не нашел про то, как эти веса указывать и устанавливать. Может они и есть, но это внутренняя кухня функции и эти веса жестко заданы изначально для каждого языка.
    В разных языках буквы с акцентами и умляутами могут иметь "базовую" букву (например, в немецком для Ö базавая буква O, а в русском для Ё - базовая буква Е), а могут не иметь (например в шведском Ö и O - совершенно разные буквы)
    Свойство sensitivity задает как различать буквы, что учитывать.
    Значениями могут быть
    'base' - не различать буквы с акцентами, не различать большие и малые (Ё == Е, Е == е);
    'accent' - различать буквы с акцентами, не различать большие и малые (Ё != Е, Е == е);
    'case' - не различать буквы с акцентами, различать большие и малые (Ё == Е, Е != е);
    'variant' - все различать (Ё != Е, Е != е).

    При этом порядок букв определяется языком. Так, если различаются акценты, то в немецком Ö идет после O (но перед P), а в шведcком Ö всегда идет после Z

    JavaScript
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    console.log('Ö'.localeCompare('O', 'de', {sensitivity: 'base'}));  // 0
    console.log('Ö'.localeCompare('P', 'de', {sensitivity: 'base'}));  // -1
    console.log('Ö'.localeCompare('O', 'de', {sensitivity: 'accent'}));    // 1
    console.log('Ö'.localeCompare('P', 'de', {sensitivity: 'accent'}));    // -1
     
    console.log('Ö'.localeCompare('O', 'sv', {sensitivity: 'base'}));  // 1
    console.log('Ö'.localeCompare('Z', 'sv', {sensitivity: 'base'}));  // 1
    console.log('Ö'.localeCompare('O', 'sv', {sensitivity: 'accent'})); // 1
    console.log('Ö'.localeCompare('Z', 'sv', {sensitivity: 'accent'}));    // 1
    Кроме этого есть свойство caseFirst, определяющее, какие буквы большие или маленькие идут первыми.
    Значениями могу быть:
    'false' (по умолчанию) - порядок определятся языком,
    'upper' - первыми идут большие буквы,
    'lower' - первыми идут маленькое буквы.

    По умолчанию в большинстве языков принят порядок, что маленькие буквы идут перед большими, хотя по кодовым точкам юникода обычно наоборот.
    JavaScript
    1
    2
    
    console.log('Ц'.localeCompare('ц', 'ru')); // 1
    console.log('Ц'.localeCompare('ц', 'ru', {caseFirst: 'upper'})); // -1
    Запись от voraa размещена 03.06.2025 в 11:22 voraa вне форума
  2. Старый комментарий
    Аватар для mr_dramm
    Цитата Сообщение от voraa
    Чего то я ничего не нашел про то, как эти веса указывать и устанавливать. Может они и есть, но это внутренняя кухня функции и эти веса жестко заданы изначально для каждого языка.
    Да веса "жестко" заданы и посмотреть их можно в этом файле allkeys.txt
    Запись от mr_dramm размещена 05.06.2025 в 11:29 mr_dramm вне форума
  3. Старый комментарий
    Аватар для voraa
    Но по этой таблице я не понимаю, почему в немецком 'Ö' идет после 'O' (это понять можно), но перед 'P', а в шведском 'Ö' идет после 'Z'? Где там ссылки на язык?
    Запись от voraa размещена 05.06.2025 в 12:05 voraa вне форума
 
Новые блоги и статьи
Модель здравосохранения 14. Собираем всю модель вместе.
anaschu 22.05.2026
Модель собрана. В будущих постах на видео я покажу, как она работает. В этом посте запускаем её, проверяем результаты и разбираем что можно с ней делать дальше. Перед запуском проверяем. . .
Модель здравоохранения 13. Добавление самой системы здравоохранения.
anaschu 22.05.2026
В предыдущем посте мы настроили болезни. Теперь добавим события, которые управляют здоровьем всего коллектива, а также настроим рабочий график и расчёт финансов. В Main создаём четыре события. . . .
Модель здравоохранения 12. добавление болезней через ресурпул, как аварии
anaschu 22.05.2026
Болезни — это ключевая часть нашей модели. Нам нужно, чтобы работник периодически уходил на больничный, его задание при этом зависало, а после выздоровления работа возобновлялась. Реализуем это двумя. . .
Модель здравоохранения 11. Создаём классы Задание и Работник
anaschu 22.05.2026
В AnyLogic каждая заявка и каждый ресурс — это объект определённого класса. Нам нужно создать два класса: Задание (заявка) и Работник (ресурс). Класс Задание В дереве проекта нажимаем правой. . .
Модель здравоохранения 10. Новая модель, смотрим, как добавлять логические блоки, и что писать внутри
anaschu 22.05.2026
Открываем AnyLogic, создаём новый проект. В дереве проекта появляется класс Main — это главный агент, в котором будет жить вся наша логика. Палитра блоков Слева находится палитра. Нас интересует. . .
модель ЗдравоСохранения 9. Новая модель, разбираемся, как ее создавать
anaschu 22.05.2026
В этой серии постов мы построим модель небольшого рабочего коллектива. Сотрудники получают задания, выполняют их, иногда болеют — и мы хотим посчитать, сколько это стоит компании. Метод. . .
[golang] Linked list
alhaos 22.05.2026
Связный список / Linked list Связный список структура данных позволяющая хранить список значений, в отличии от массива в памяти хранится не сплошным куском, а отдельными частями которые ссылаются. . .
[golang] Двоичная куча, min-heap
alhaos 20.05.2026
Двоичная куча Двоичная куча — структура данных, которая всегда держит самый важный элемент наготове. Представьте очередь к хилеру в игре, и очередь из игроков в приоритете те у кого меньше. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru