#BecauseJavaScript Part 2 – String Comparisons

Welcome back!

I delved into Twitter again and found this little tweet by Nico Castro. This is a quick one, but it does need a fair bit of explanation to clarify things.

So what’s going on here? Why is the small ‘a’ greater than capital ‘Z’, but at the same time has capital ‘A’ not greater than capital ‘Z’?

Nico is on the right track, ASCII has a lot to do with it, but it’s a teeny tiny bit more complex than that… Let’s take another look at those two statements:

"a" > "Z" // true

"A" > "Z" // false

So, as I said, there is some focus on the ASCII component of the strings that comes into play.

Let’s replace the strings with their ASCII numeric equivalents. Once we do, we see something that instantly clicks:

97 > 90 // "a" > "Z" == true!

65 > 90 // "A" > "Z" == false!

Ta-dah! JavaScript has this unique way with comparing strings when it comes to the greater-than and lesser-than operators. In comparing strings, JavaScript treats them as arrays comprised of single character elements, so in the first example, JavaScript is really comparing [“a”] against [“Z”], JavaScript then compares both arrays, index by index.

Here are three more examples…

"ab" > "ac" // false
"ab" > "a" // true
"ate" > "are" // true

The first example gets converted to their respective arrays: [“a”,”b”] and [“a”,”c”], and then runs through the conversions to the numeric equivalents: [97,98] and [97, 99]. From there, JavaScript will compare these two arrays index by index until it finds a pair that satisfies the comparison operator in question. If it cannot find a pair of elements satisfying the comparison false is returned, otherwise it will return true. If, however, we find a pair of elements that does satisfy the comparison, it returns true and breaks out of the check. So in this first example, the zeroth element for both arrays is 97. 97 isn’t greater than 97, so it then tests out the first elements of, 98 against 99, 98 is not greater than 99, and thus because we’ve reached the end of both arrays without anything satisfying the comparison, it returns false.

Second example is slightly trickier. We have a two character-long string compared against a single character. What happens there?

If you were to type “a”[0] into a JavaScript console, you’d get returned “a”, the zeroth element in the array. So far, so good. However, were you then to type “a”[1] into the console, you’d get returned undefined, which makes sense because in a single element array there will only the element at index 0, and no other, so any index above zero will return undefined.

So “a” which we know is the same as [“a”] is also technically equivalent to [“a”, undefined]!

In short, when comparing strings with greater-than or lesser-than operators, the shorter string will be “appended” with undefined instances when converted to an array until both arrays are of equal length before doing the final series of comparisons. And because undefined is a falsy value, when compared, the undefined gets coerced to 0.

With all that said and done, we finally end up with: [97,98] (“ab”) and [97,0] (“a”). Comparing the two arrays, We get the zeroth elements not satisfying the > operator, but the first elements do, so true is returned.

Finally, we compare “ate” with “are”. When both strings are converted to numeric arrays for comparison we have [97, 116, 101] and [97, 114, 101] . The rest is a foregone conclusion:

Index 0; is 97 > 97? No, move onto index 1.

Index 0; is 116 > 114? Yes! Ding Ding Ding! Stop processing and return true.

So there you have it, string comparisons with lesser-than and greater-than operators. And yes, it’s a pain in the ass that JavaScript computes comparisons like this, but once you stop and look at the process of how it does it, there’s a greater appreciation of how the language works.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s