Thursday, July 10, 2008

Javascript and Numbers

Today I was working on improving a javascript function that sorts an HTML table that I originally wrote about 5 years ago.

The problem that I have is that I am a novice in javascript. Well, novice is probably overestimating my capabilities in actuality. But anyway, I still needed to improve this function, and learn along the way.

The function checks the first cell in the first row of a table in an attempt to determine the data type of the column. This is important when looking at numbers and dates. For example numerically, these numbers (1, 3, 2, 4, 30 , 10) would expect to be sorted as (1, 2, 3, 4, 10, 30). However if sorted as text, you end up with (1, 10, 2, 3, 30, 4). That is not what I was trying to do, but that is what my code kept throwing out. Same with any decimal numbers, especially when the decimal point was in different spots (Different precision).

Previously, I was using a regular expression to match numeric values. I was using the expression /^[\d\s]+$/ which leaves a lot to be desired. Besides the overhead of using an regular expression to begin with.

My first thought was to use a string parser and just look for the numbers 0-9 and the +- and decimal characters. However that would attempt to sort a value of '++0124.543.56.4-8;' as a number. I could have written in a check to see if there was exactly one + or - and exactly 1 decimal point, but that would have been a messy bit of code. It may have worked but it would look bad and be low on performance.

Then I thought about some of my VB experience and decided to apply it to the problem. Why try to see if the number is a number? why not just try to convert it and let the javascript engine handle it. Odds are the javascript engine programmers are way smarter than I will ever be.

With that in mind, I wrote a quick function. And by quick I mean one line. Here it is.

function IsNumeric(checkStr){return checkStr.length > 0 && (checkStr - 0) == checkStr;}

The function IsNumeric takes one input string. The function does 2 comparisons to that string, and both must return true in order for the fucntion to return true. First, the input string must have a non-zero length. This is done because a string of length zero should not be considered a number. The second check is a little more complicated.

First, javascript doesn't have explicit type conversion. Meaning I can't cast a variable as a double. But we can force the javascript engine to use the string as a number by trying to subtract a zero from it. If the conversion to a number fails, the javascript engine will return a NaN, meaning Not a Number. Finally, the now numeric checkStr is compared to the input string to see if they are equal. If they are, true will be returned.

I was unable to find a number that returns false or a string that returns true, so this seems pretty solid. If you have a better solution, I would love to hear about it. Please post it in the comments section.