Nerd For Tech

NFT is an Educational Media House. Our mission is to bring the invaluable knowledge and experiences…

Follow publication

Basics of Javascript · String · localeCompare() (method)

--

This article is a transcript of my free youtube series about basics of web development. If you prefer watching over reading, feel free to visit my channel “Dev Newbs”.

Hello dev newbs! The method that we will cover today is of special importance to me and probably to all of you that come from the country that uses special characters in their alphabet. By the way, I am from Slovakia and we have a lot of diacritic marks in our words and names. So if you are like me and you need to order words, names, or whatever made of strings, this is the method for you.

LocaleCompare() method returns a number which indicates whether a reference string belongs alphabetically before, or after, or is the same as the given string in sort order. This method compares two strings in the current locale. The locale is based on the language settings of the browser.

The parameters of the method are as follows:

  • compared string — the string used to compare against referenced string
  • locales — value to specify what language to use for comparison
  • options — object containing arguments that allow to further specify the behaviour of the method

The locales & options might not be implemented in the same manner in all browsers. If they are not implemented at all, they will be ignored. There is a way of specifying the same attributes both in locales and options, but there are three reasons why I won’t teach you how to do it within locale setup. First is already mentioned — it is not implemented in each browser. Second is that I don’t like it because it’s very clumsy. The third is that you can override these settings in the options object anyway.

The number that you get as a result is one of these three options:

  • negative number — if the reference string is alphabetically before compared string
  • 0 if two strings are equal
  • positive number if the reference string is alphabetically after compared string

Because W3C specification does not specify using exact numbers, only the positivity and negativity of the result number, some browsers can provide 1/-1, others can provide 2/-2 or even completely different values. So only check whether the value returned is more or less or equal to zero.

Ok, so much for the definition. Let’s see the method in action.

// 0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ{
let referenceStr = "0";
let compareString = "9";
// '0' is alphabetically before '9'
referenceStr.localeCompare(compareString) // -1
}
{
let referenceStr = "9";
let compareString = "a";
// '9' is alphabetically before 'a'
referenceStr.localeCompare(compareString) // -1
}
{
let referenceStr = "a";
let compareString = "A";
// 'a' is alphabetically before 'A'
referenceStr.localeCompare(compareString) // -1
}
{
let referenceStr = "A";
let compareString = "b";
// 'A' is alphabetically before 'b'
referenceStr.localeCompare(compareString, 'en') // -1
}

I included a comment at the beginning of the example to show the sort order for the most common characters — that is numbers, then alphabet letters with leading lowercase letter followed by uppercase letter in the alphabetical order. The four example results confirm this basic ordering.

Now, we talked about diacritic marks and the fact that some languages have different variations of the basic letters. For example both Germans and Swedes know the letter “ä”. But there is a difference in the way how their locale handles this letter. We will have a look at this in the second example:

// a negative value: in German, ä sorts before z
'ä'.localeCompare('z', 'de') // -1
// a positive value: in Swedish, ä sorts after z
'ä'.localeCompare('z', 'sv') // 1
// in German, ä has a as the base letter
'ä'.localeCompare('a', 'de', { sensitivity: 'base' }) // 0
// in Swedish, ä and a are separate base letters
'ä'.localeCompare('a', 'sv', { sensitivity: 'base' }) // 1

First pair of results shows us that for Germans, “ä” comes before the letter “z”, but for the Swedes, they put their characters with diacritic marks after the base set of letters of the alphabet.

Similar situation is in the second pair of results which illustrates the difference between two locales regarding the “baseness” of the letter. For Germans, “ä” is just the base letter “a” with an extra diacritic mark. They do not consider this a separate letter. On the other hand, Swedes consider it a separate letter.

Okay, so that’s that. If you thought that locales are bad, prepare for a treat. We are going to cover options now.

Now, there are more attributes available for the options object, but I will cover only those that worked for me and actually made sense to use. Feel free to check the rest.

First and probably most often used one is attribute “sensitivity”. You can set it to one of the following four values:

  • base
  • accent
  • case
  • variant (default)

When we use sensitivity option three checks are done on each compared pair of letters:

  • whether two base letters should be considered equal
  • whether base letter and version with diacritic mark should be considered equal
  • whether uppercase and lowercase version of letter should be considered equal

Each of the four available sensitivity options sets a different combination of these checks. You can see it in the following example.

// options - sensitivity
// 'BASE: a ≠ b, a = á, a = A'
'a'.localeCompare('b', 'en', { sensitivity: 'base' }) // -1
'a'.localeCompare('á', 'en', { sensitivity: 'base' }) // 0
'a'.localeCompare('A', 'en', { sensitivity: 'base' }) // 0
// 'ACCENT: a ≠ b, a ≠ á, a = A'
'a'.localeCompare('b', 'en', { sensitivity: 'accent' }) // -1
'a'.localeCompare('á', 'en', { sensitivity: 'accent' }) // -1
'a'.localeCompare('A', 'en', { sensitivity: 'accent' }) // 0
// 'CASE: a ≠ b, a = á, a ≠ A'
'a'.localeCompare('b', 'en', { sensitivity: 'case' }) // -1
'a'.localeCompare('á', 'en', { sensitivity: 'case' }) // 0
'a'.localeCompare('A', 'en', { sensitivity: 'case' }) // -1
// 'VARIANT (default): a ≠ b, a ≠ á, a ≠ A'
'a'.localeCompare('b', 'en', { sensitivity: 'variant' }) // -1
'a'.localeCompare('á', 'en', { sensitivity: 'variant' }) // -1
'a'.localeCompare('A', 'en', { sensitivity: 'variant' }) // -1

You can check the combination setup for each sensitivity value in the comment line. The default one if no sensitivity is provided, is “variant”, which is the most sensitive one.

The last example will show two other attributes and that is “numeric” which specifies whether to compare two strings as if they represented a number. The default setting is false.

Interesting is that even if you define numeric attribute with value false, Chrome still behaves as if you chose “true”. In a way, it makes sense, because what would be the reason to specify numeric as false, when it is false by default? But I think that still — it’s a bit of a lazy approach to implementation.

The other attribute I want to mention is “caseFirst” which decides which of the lowercase/uppercase version of a letter comes first.

Its values can be:

  • upper — uppercase is first
  • lower — lowercase is first
  • false (default) — use the locale’s default sorting

Okay, enough was said, here are the examples:

// options - numeric
// 'NUMERIC: true, false (default)'
'2'.localeCompare('10', undefined)
'2'.localeCompare('10', undefined, { numeric: 'true' })
'2'.localeCompare('10', undefined, { numeric: 'false' })
// options - caseFirst
// 'CASE FIRST: upper, lower, false (default)'
'a'.localeCompare('A', 'en', { caseFirst: 'upper' })
'a'.localeCompare('A', 'en', { caseFirst: 'lower' })
'a'.localeCompare('A', 'en', { caseFirst: 'false' })

Just bear in mind that if you run the examples in the different browser or the same browser, but a very different version, the results might differ. Also, if your default locale is not the same as mine, the results might differ a bit.

That’s that for the day. I know it was a lot, but if you made it here, enjoy. It is over and you did well.

As always thank you for the attention and I will see you in the next article.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Nerd For Tech
Nerd For Tech

Published in Nerd For Tech

NFT is an Educational Media House. Our mission is to bring the invaluable knowledge and experiences of experts from all over the world to the novice. To know more about us, visit https://www.nerdfortech.org/.

Jakub Korch
Jakub Korch

Written by Jakub Korch

Web enthusiast, programmer, husband and a father. Wannabe entrepreneur. You name it.

No responses yet

Write a response