Different result between localCompare and comparison operator for special characters in JavaScript

While looking at one issue related to sorting, I came across interesting difference for non alpha numeric characters comparison between string localeCompare method and conditional operator (like >,<).

You can see difference between them by running below snippets in different browsers.

function comparison1(param1, param2){
  return param1 > param2;
}

function comparison2(param1, param2){
  return param1.localeCompare(param2);
}
document.getElementById("comparison11").innerHTML = comparison1('A', 'B');
document.getElementById("comparison12").innerHTML = comparison2('A', 'B');
document.getElementById("comparison21").innerHTML = comparison1('@', '_');
document.getElementById("comparison22").innerHTML = comparison2('@', '_');
<div>
  <div style="float: left, width: 100%">
    'A' > 'B'
  </div>
  <div style="float: left, width: 100%" id="comparison11"></div>
  <div style="float: left, width: 100%">
    'A'.localeCompare('B')
  </div>
  <div style="float: left, width: 100%" id="comparison12"></div>
  <div style="float: left, width: 100%">
    '@' > '_'
  </div>
  <div style="float: left, width: 100%" id="comparison21"></div>
  <div style="float: left, width: 100%">
    '@'.localeCompare('_')<br/>
    <i>returns -1 in IE and Edge but 1 in Chrome and Firefox</i>
  </div>
  <div style="float: left, width: 100%" id="comparison22"></div>

</div>
<script>
</script>

As you can see there is difference in response while comparing '@' and '_' when using localeCompare method and > operator in Chrome and Firefox.

We implemented comparison method for sorting that is called for multiple columns with different data types. So we used conditional operators, but as you can see it is providing different result for non alpha numeric characters in different browsers.

Here are my questions!

Why different response for special characters in different browsers?

What is correct way to implement this? (Check data type; if string use localeCompare else conditional operator?)

Answers:

Answer

Why different response for special characters in different browsers?

Probably because as it says in the ECMA-402 (internationalization) spec:

Subsets of Unicode: Some operations, such as collation, operate on strings that can include characters from the entire Unicode character set. However, both the Unicode standard and the ECMAScript standard allow implementations to limit their functionality to subsets of the Unicode character set. In addition, locale conventions typically don’t specify the desired behaviour for the entire Unicode character set, but only for those characters that are relevant for the locale. While the Unicode Collation Algorithm combines a default collation order for the entire Unicode character set with the ability to tailor for local conventions, subsets and tailorings still result in differences in behaviour.

Most likely, the order of @ vs. _ just isn't significantly defined in the locales you're using (or mine; UK English), and so you get "differences in behavior."

What is correct way to implement this? (Check data type; if string use localeCompare else conditional operator?)

Yes. > and < use the numeric relationship of the code points in the Unicode standard, which isn't really a very good way to handle collation at all, while localeCompare provides a locale-specific collation to characters.

To be clear: When you say you "...used conditional operator", I assume you mean the conditional operator (? :) combined with a relational operator (> or < in this case), e.g. something like:

return a === b ? 0 : a > b ? 1 : -1;

...or similar in a sort callback.

But note that since you're now using localeCompare for strings, and the only other thing you can really meaningfully compare with > and < is numbers, there's a better solution for numbers if you know none of them is NaN: Just subtract:

return a - b; // For numbers that aren't NaN

(If either of them may be NaN, you'll want to handle that — perhaps with the conditional operator. :-) )

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.