I first encountered the
.localeCompare() method while doing a Codewars kata that asked you to write a function that first sorted an array of attendee objects by their
language key, and if they were the same, then sort by their
Admittedly, I spent two days on this problem because I couldn’t get the sorting done correctly. After finally figuring out a brute force solution, I got a chance to look at the other solutions and that was the first time I’d ever seen the
.localeCompare() in the MDN Web Docs
As usual, when I first come across a new method, I look it up on the MDN Web Docs.
localeCompare()method returns a number indicating whether a reference string comes before, or after, or is the same as the given string in sort order.
localeCompare(compareString, locales, options)
In other words, this is a string method that compares two strings and tells you whether or not one comes before, after, or is the same as the other. As seen in its syntax, there is flexibility to add locales, or languages to use, and options based on the locale. However, the simplest way to use the method is to call it on a string and pass another string that you'd like to compare it against.
“Does the given string come before the string I called the method on?”
Since the method actually returns a number, the following responses are expected:
1- “Yes it does come before”
-1- “No it does not come before”
0- “They are the same”
Solving the Codewar Kata WITHOUT
At first I thought I could just use an if statement to check if the languages were the same, and if so, use their firstNames to compare against each other. Otherwise, it would just compare the languages.
The actual comparison was what I had originally learned of the
sort method, namely using
a-b as the compare function (this is one of the examples from MDN ):
[4, 2, 5, 1, 3].sort((a, b) => a - b);
I realize now that, the
a-b portion only works because the elements in the array are numbers. It doesn’t work the same way with strings. With strings, it’s better to use the
.toLowerCase() on both before comparing).
Eventually, I figured out a very roundabout solution, which involved several (unnecessary) steps:
- Sorting the languages themselves
- This involved first finding all the unique languages in the original list (done by using a Set). Then I turned it back into an array so I could sort them.
- Filtering the attendees into their own array based on the language they used and sorting those.
- Creating a new list by adding those arrays and returning the new list.
Yes, very confusing stuff and way, way, way lengthier than the top solution. Even I was surprised when it worked 😅
Considering complexity, both in time and memory, it’s a disaster. Especially at the step where I create a new Set and turn it back into an array, that’s got to be breaking at least five “coding best practices.”
Solving the Codewar Kata WITH
We’ve already seen the
.localeCompare() solution for this kata, but let’s break it down and see how the it’s used.
This solution makes use of the fact that the
.sort() method sorts an array in place so we can return it without storing it in a variable, and uses the ternary operator to skip writing out a full if-else statement.
The real meat and potatoes of the code is the actual callback function being passed into the sort method, which is used to compare the elements in the array.
(a,b) => a.language === b.language ? a.firstName.localeCompare(b.firstName) : a.language.localeCompare(b.language)
The first part is to check whether the languages are the same:
a.language === b.language
If it evaluates to true, the first part of the ternary will execute, or in other words, it will sort the attendees based on their firstName.
Otherwise, it will simply sort the attendees based on their language.
Remember that the
.localeCompare() method is asking, “Does b come before a?” and based on the value returned, the sort method will move the elements appropriately. It will do that for all the elements in the array and then return the newly sorted list.
And that’s it! A single-line solution compared to my 12-line brute force solution.
Thanks for reading!
💖 Geraldine | Say hi on Twitter 👋🏾 @geraldinedesu