Sorting Strings with Accented Characters

By  on  

Strings can create a whole host of problems within any programming language.  Whether it's a simple string, a string containing emojis, html entities, and even accented characters, if we don't scrub data or make the right string handling choices, we can be in a world of hurt.

While looking through Joel Lovera's JSTips repo, I spotted a string case that I hadn't run into yet (...I probably have but didn't notice it):  sorting accented characters to get the desired outcome.  The truth is that accented characters are handled a bit differently than you'd think during a sort:

// Spanish
['único','árbol', 'cosas', 'fútbol'].sort();
// ["cosas", "fútbol", "árbol", "único"] // bad order

// German
['Woche', 'wöchentlich', 'wäre', 'Wann'].sort();
// ["Wann", "Woche", "wäre", "wöchentlich"] // bad order

Yikes -- accented characters don't simply follow their unaccented character counterparts.  By taking an extra step, i.e. localeCompare, we can ensure that our strings are sorted in the way we likely wanted in the first place:

['único','árbol', 'cosas', 'fútbol'].sort(function (a, b) {
  return a.localeCompare(b);
});
// ["árbol", "cosas", "fútbol", "único"]

['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(function (a, b) {
  return a.localeCompare(b);
});
// ["Wann", "wäre", "Woche", "wöchentlich"]

// Or even use Intl.Collator!
['único','árbol', 'cosas', 'fútbol'].sort(Intl.Collator().compare);
// ["árbol", "cosas", "fútbol", "único"]

['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(Intl.Collator().compare);
// ["Wann", "wäre", "Woche", "wöchentlich"]

Localization is already a big challenge without the added confusion that comes with accented characters.  Keep localeCompare and Intl.Collator in mind every time you want to sort strings!

Recent Features

  • By
    Create a CSS Flipping Animation

    CSS animations are a lot of fun; the beauty of them is that through many simple properties, you can create anything from an elegant fade in to a WTF-Pixar-would-be-proud effect. One CSS effect somewhere in between is the CSS flip effect, whereby there's...

  • By
    5 Awesome New Mozilla Technologies You’ve Never Heard Of

    My trip to Mozilla Summit 2013 was incredible.  I've spent so much time focusing on my project that I had lost sight of all of the great work Mozillians were putting out.  MozSummit provided the perfect reminder of how brilliant my colleagues are and how much...

Incredible Demos

  • By
    CSS pointer-events

    The responsibilities taken on by CSS seems to be increasingly blurring with JavaScript. Consider the -webkit-touch-callout CSS property, which prevents iOS's link dialog menu when you tap and hold a clickable element. The pointer-events property is even more JavaScript-like, preventing: click actions from doing...

  • By
    MooTools HTML Police: dwMarkupMarine

    We've all inherited rubbish websites from webmasters that couldn't master valid HTML. You know the horrid markup: paragraph tags with align attributes and body tags with background attributes. It's almost a sin what they do. That's where dwMarkupMarine comes in.

Discussion

  1. only problem is that this approach is slower, there is a solution which is to use a Intl.Collator object which speeds things up

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare

    It has other benefits too, such as support for numeric sorts, aka natural or human sorting, so that numerics are also sorted as humans expect, i.e 10 comes after 2

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator

  2. Nifty, except that ["Wann", "wäre", "Woche", "wöchentlich"] is not the correct order when sorting in German. So it’s not really internationalized, it’s just sorting in a way an English speaker would prefer. A native German would be very confused if you sorted thing this way.

    • Of course if localeCompare is run in the browser, and the user has a German language setting, it would be sorted as expected. My point is that it is dangerous to assume that all languages are sorted the same way.

    • Sébastien

      localeCompare accept a language argument so you could pass de as argument to sort even if the browser is set to English.

  3. Gustavo Costa

    Is it possible to sort mixed numbers (numerically by first) and accented or non-accented letters (alphabetically by second)?

  4. Gustavo Costa

    Test with this:

    "3", "2", "10", "40", "6", "4", "30", "33", "1", "Gustavo", "julho", "Klaus", "keyboard", "último", "árbol", "uma", "água", "Argentina", "Ángelo", "argelino", "unido"

    .

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!