Agent Wranglers

LOC-15Recommended

Sort and compare text by locale

Sort and compare visible text with a collator for the reader's locale, and normalise Unicode before comparing or storing it.

How to do it

Sort lists with a locale collator, such as Intl.Collator in JavaScript, PyICU in Python or java.text.Collator. Byte order puts "Ö" in the wrong place, and the right place differs by language. Normalise input to NFC, so "é" typed two ways compares equal. Change case with the locale, because Turkish lower-cases "I" to "ı".

Examples

JavaScript example

const words = ['ä', 'a', 'z', 'o', 'ö'];
words.sort(new Intl.Collator('sv').compare); // ["a", "o", "z", "ä", "ö"]
words.sort(new Intl.Collator('de').compare); // ["a", "ä", "o", "ö", "z"]
'Cafe\u0301'.normalize('NFC') === 'Café'; // true

Python example

import unicodedata
from icu import Collator, Locale
swedish = Collator.createInstance(Locale("sv_SE"))
sorted(["ä", "a", "z", "o", "ö"], key=swedish.getSortKey)  # ['a', 'o', 'z', 'ä', 'ö']
unicodedata.normalize("NFC", "Cafe\u0301") == "Café"  # True

Java example

import java.text.Collator;
import java.text.Normalizer;
import java.util.*;
List<String> words = new ArrayList<>(List.of("ä", "a", "z", "o", "ö"));
words.sort(Collator.getInstance(Locale.forLanguageTag("sv")));  // [a, o, z, ä, ö]
Normalizer.normalize("Cafe\u0301", Normalizer.Form.NFC).equals("Café");  // true

How to check

A unit test sorts a fixed list per locale and gets the expected order. Swedish puts "ä" after "z", and German puts it after "a".

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/localization/dates-numbers-and-text/locale-collation">Agent Wranglers localization playbook</a>. In code you write, add a comment next to it with the same link.