DEV Community

Cover image for How to sort an array alphabetically
Adam LaCombe
Adam LaCombe

Posted on • Originally published at adamlacombe.com on

How to sort an array alphabetically

String.localeCompare()

If you're working with a relatively small array, you could use localeCompare().

const arr = [
  {
    name: "Orange"
  },
  {
    name: "Banana"
  },
  {
    name: "Carrot"
  },
  {
    name: "Apple"
  }
];

// [{"name":"Apple"},{"name":"Banana"},{"name":"Carrot"},{"name":"Orange"}]
console.log(arr.sort((a, b) => a.name.localeCompare(b.name)));
Enter fullscreen mode Exit fullscreen mode

Intl.Collator()

If you're working with a large array, I would recommend using Intl.Collator() for performance reasons.

const arr = [
  {
    name: "Orange"
  },
  {
    name: "Banana"
  },
  {
    name: "Carrot"
  },
  {
    name: "Apple"
  }
];
const collator = new Intl.Collator();

// [{"name":"Apple"},{"name":"Banana"},{"name":"Carrot"},{"name":"Orange"}]
console.log(arr.sort((a, b) => collator.compare(a.name, b.name)));
Enter fullscreen mode Exit fullscreen mode

Benchmarks

1,000 strings

Here is a benchmark where we're sorting an array of 1,000 strings. As you can see, Intl.Collator() is 25% faster than localeCompare().

Benchmark 1,000 strings

25 strings

Here is a benchmark where we're sorting an array of only 25 strings. In this case, localeCompare() is 13% faster than Intl.Collator().

Benchmark 25 strings

Top comments (12)

Collapse
 
rtivital profile image
Vitaly Rtishchev

It's still faster in all cases to compare on your own

arr.sort((a, b) => {
  const lowerA = a.toLowerCase();
  const lowerB = b.toLowerCase();

  if (lowerA < lowerB) {
    return -1;
  }
  if (lowerB < lowerA) {
    return 1;
  }
  return 0;
});
Enter fullscreen mode Exit fullscreen mode

alt

Collapse
 
bryceamcdaniel profile image
BryceAMcDaniel

This doesn’t take into account internationalization though, correct?

Collapse
 
adamlacombe profile image
Adam LaCombe

Correct. I made a quick codepen showing the difference when sorting some characters from the German alphabet codepen.io/adamlacombe/pen/ZEOezeq...

Collapse
 
rtivital profile image
Vitaly Rtishchev

why not? all characters follow the same rules

Thread Thread
 
bryceamcdaniel profile image
BryceAMcDaniel
Thread Thread
 
rtivital profile image
Vitaly Rtishchev

yep, this is exact the same behaviour that is expected from sorting – first latin letters then everything else – this is how sorting works in all applications and i cannot imagine why would you want to sort another way

Thread Thread
 
bryceamcdaniel profile image
BryceAMcDaniel

“This is how sorting works in all applications”
Umm no.

“I cannot imagine why would you want to sort any other way”
How about sorting user last names? Usernames? Emails? For directory listing? Literally any string you would like to maintain locale specific sorting.

Thread Thread
 
adamlacombe profile image
Adam LaCombe

@rtivital Take this array of german strings for example: ['Bären', 'küssen', 'Käfer', 'Ähnlich', 'Äpfel']

Sorting it using the method you provided will result in ["Bären", "Käfer", "küssen", "Ähnlich", "Äpfel"] which isn't correct.

The sorted array should look like ["Ähnlich", "Äpfel", "Bären", "Käfer", "küssen"]

There is a reason these locale functions exist.

Thread Thread
 
rtivital profile image
Vitaly Rtishchev

Yes, that makes sense. But there is another side of that – similar letters of different locales, for example, in Russian language we have a letter "а", which is treated the same as latin "a". For any interface in Russian language we have separation between these two alphabets and it is unimaginable to work with them in any other way (see screenshot of iPhone apps list – on the right there are sorted alphabets, Я is the last letter of Russian alphabet). I get your point that the sorting you've shown works with german, but it does not for this cases. I guess the optimal strategy here will be to first sort by locale and only then sorting by your way.
a

Thread Thread
 
bryceamcdaniel profile image
BryceAMcDaniel

I think you’re missing the point of locale specific sorting.

Can you fork my sandbox and show me where the sorting is not correct?

Thread Thread
 
adamlacombe profile image
Adam LaCombe • Edited

Interesting. I see your point. iPhone definitely sorts things differently than I would expect though. That may be because each app manifest indicates its language so they're able to separately sort russian and then english apps.

I created another codepen that sorts ['Я', 'ю', 'б', 'а', 'а', 'z', 'b'] using Intl.Collator(['ru', 'en']) which results in ["а", "а", "б", "ю", "Я", "b", "z"].

If we were to switch the locale order to `['en', 'ru']` it would result in `["b", "z", "а", "а", "б", "ю", "Я"]` So the order of strings with characters that exist in both locale will be sorted according to the first locale. I hope that makes sense.

Check out the documentation on Locale negotiation

Thread Thread
 
rtivital profile image
Vitaly Rtishchev

@bryceamcdaniel Oh, now I see, It works as expected, did not notice that when was trying your sandbox the first time. Then it covers everything and can be used for these tasks.