kip

kip

ex_cldr Core Team

Cldr Collation - language-aware string sorting and comparison with opt-in NIF

Announcing ex_cldr_collation version 1.0

ex_cldr_collation is an Elixir implementation of the Unicode Collation Algorithm (UCA) as extended by CLDR, providing language-aware string sorting and comparison. An opt-in NIF is provided for high performance collating.

ex_cldr_collation has no dependency on ex_cldr but if it is configured in your app, Cldr.LanguageTag.t locales can be passed as a :locale option.

Features

  • Full Unicode Collation Algorithm implementation in pure Elixir.

  • CLDR root collation based on the Unicode DUCET table.

  • Locale-specific tailoring for 10+ languages (Danish, German phonebook, Spanish, Swedish, Finnish, etc.)

  • All BCP47 -u- extension collation keys supported.

  • Optional high-performance NIF backend using ICU4C.

  • Sort key generation for efficient repeated comparisons.

Examples

There are lots of options to affect locale-specific and user-specific sort requirements. Here are just some basic examples:

iex> Cldr.Collation.sort(["café", "cafe", "Cafe"])
["cafe", "Cafe", "café"]

# Cased comparisons
iex> Cldr.Collation.sort(["café", "cafe", "Cafe"], case_first: :upper)
["Cafe", "cafe", "café"]

iex> Cldr.Collation.compare("café", "cafe")
:gt

iex> Cldr.Collation.compare("a", "A", casing: :insensitive)
:eq

# Numeric ordering. Note that the normal order places
# the 1 before the 2
iex> Cldr.Collation.sort(["Level 10", "Level 2"], numeric: true)
["Level 2", "Level 10"]

# But numeric sorting takes consecutive digits into account,
# and not just Indo-arabic digits - any digits in any script.
iex> Cldr.Collation.sort(["Level 10", "Level 2"], numeric: false)
["Level 10", "Level 2"]

# German phonebook ordering
iex> words = ["Ärger", "Alter", "Ofen", "Öl", "Über", "Ulm"]

iex> Cldr.Collation.sort(words)
["Alter", "Ärger", "Ofen", "Öl", "Über", "Ulm"]

iex> Cldr.Collation.sort(words, locale: "de-u-co-phonebk")
["Ärger", "Alter", "Öl", "Ofen", "Über", "Ulm"]

# Locale-based ordering
iex> Cldr.Collation.compare("a", "A", locale: "en-u-ks-level2")
:eq

# Sort key generation
iex> Cldr.Collation.sort_key("hello")
<<36, 196, 36, 83, 37, 40, 37, 40, 37, 152, 0, 0, 0, 32, 0, 32, 0, 32, 0, 32, 0,
  32, 0, 0, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2>>

Implementation notes

Like unicode_transform, Claude was a very valuable co-developer for this release. The same value proposition makes this a very powerful combination for development and testing:

  • The specification is clear and complete so easy to ingest for an LLM
  • There is a reference implementation against which test validation can run automatically. The NIF-based interface to ICU makes this almost trivial.

https://github.com/elixir-cldr/cldr_collation

Where Next?

Popular in Announcing Top

danschultzer
In short Plug n’ play OAuth 2.0 provider library. Just set up a resource owner schema with Ecto (your user schema), install the dependen...
New
asiniy
Hey there! I wrote a download elixir package which does exactly what its name about - an easy way to download files. I saw solutions ab...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
woutdp
Hi! I wanted to introduce my latest project LiveSvelte. It allows you to render Svelte inside LiveView with end-to-end reactivity. It’s ...
New
blatyo
The best overview for how things are tied together is this presentation. Modules and functions are pretty well documented at this point, ...
New
markmark206
simple_feature_flags is a tiny package that lets you turn features on or off based on which environment (e.g. localhost, staging, product...
New
anshuman23
Hello all, I have been working on my proposed project called Tensorflex as part of Google Summer of Code 2018.. Tensorflex can be used f...
New
zoltanszogyenyi
Hey everyone :waving_hand: Excited to join this forum - I am one of the founders and current project maintainers of a popular and open-s...
New
kevinlang
Hey all, We have made an Ecto3 Adapter for SQLite3, ecto_sqlite3! We have successfully on-boarded the full suite of integration tests (...
New
trisolaran
Hi! :waving_hand: I would like to present LiveSelect, a little library that I wrote to easily add a dynamic selection input to your LV f...
198 10858 107
New

Other popular topics Top

danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29377 241
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43622 214
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 53690 245
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New

We're in Beta

About us Mission Statement