0

I have 2 strings:

var a = 'António'
var b = 'António'

But when I compare them:

if(a == b)

They are not equal. How can a make that true?

JJJ
  • 32,902
  • 20
  • 89
  • 102
  • If i copy/paste i get true for `var a = 'António', b = 'António'; a == b` if you do not then one of the strings has a charcter(s) difference, this may include invisible unicode characters. Please provide a test case that returns `false`. – Alex K. May 04 '17 at 10:33
  • While I am checking it in console it shows true var a = 'António' , b = 'António' console.log(a==b?true : false) – Nair Athul May 04 '17 at 10:33
  • @NairAthul `(a==b)?true : false`...C'mon - You can't do that – Weedoze May 04 '17 at 10:35
  • try it in console. It will give you result :) – Nair Athul May 04 '17 at 10:36
  • 4
    (a==b) *already* returns true|false – Alex K. May 04 '17 at 10:38
  • Possible duplicate of [Javascript string comparison fails when comparing unicode characters](http://stackoverflow.com/questions/10805711/javascript-string-comparison-fails-when-comparing-unicode-characters) – JJJ May 04 '17 at 10:55

4 Answers4

1

You can use the String.prototype.localeCompare() method.

stringA.localeCompare(stringB);

/* Expected Returns:

 0:  exact match

-1:  stringA < stringB

 1:  stringA > stringB

 */
Henry Woody
  • 14,024
  • 7
  • 39
  • 56
1

Your problem happens because your 'ó' character might be expressed differently.

You can obtain the same grapheme by writing:

  1. Using the Unicode character

    var a = 'António'

  2. Using the Unicode code point

    var b = 'Ant\u00F3nio'

  3. Using a combining mark ('o' + '´')

    var c = 'Anto\u0301nio'

The last one combines 'o' (latin small letter o) with '´' (accute accent).

Now if you do a === b you will get true. Because in this case I used the Unicode character and compared it with its code point which is the same thing.

Now if you do a === c you will get false. Because the first one is one Unicode character and the second one is combining an Unicode character with a combining mark obtaining the same grapheme.

Now if I'm pasting a and c output in the console, then copy pasting them into other variables and comparing them, I will get the same thing.

Doing: var x = 'António' (from a) and var y = 'António' (from c) then x === y will get false. If you try this in your browser console and you get false then is right, else SO might have processed the string and no wonder others got true.

In order to compare a ('António') with c ('Anto\u0301nio'), you need to normalize the form in order to get the same thing.

Therefore you can do:

NFC (Canonically-composed form) (the default)

a === c.normalize('NFC') or just a === c.normalize()

Therefore this makes c to be represented the same as a.

NFD (Canonically-decomposed form)

a.normalize('NFD') === c

Therefore this makes a to be represented the same as c.

Or you can just rely on one form for both sides and don't mind the format used to represent any of the strings:

a.normalize() === c.normalize()

NOTE: JavaScript engines use UTF-16. This means that if your character is in the Basic Multilingual Plane having the code point between U+0000 and U+FFFF you will be good. But if you use some character above that range (Astral Planes) then that character will be represented using surrogate pairs thus having two code units 16-bit each. In that case some operations might not yield the expected behavior if the string is not normalized.

NOTE: for a good read you can check this.

Community
  • 1
  • 1
andreim
  • 3,365
  • 23
  • 21
-1

a == b returns true for me. As a side note you should probably use ===

Josh Wilson
  • 3,585
  • 7
  • 32
  • 53
-1

var a = "António";
var b = "António";

$(document).ready(function(){
 if(a == b){
   alert(true);
  }else{
   alert(false);
  }
});
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>