Skip to Content
Author's profile photo Former Member

Quiz series: Micro JavaScript / Is this a number???

The question was inspired by the following post in Russian Software Developers Networks: http://rsdn.ru/Forum/Message.aspx?mid=2047058&only=1 . The text above first code snippet in English: “We got one project with the following legacy code…”

Besides being a good candidate for DailyWTF column, this code snippet provokes a question: how much effort is necessary to verify that supplied string is in fact Number? So here is one-question quiz for JavaScripters.How many characters you need for <expression> to verify that variable s holds a ‘number’ as content?

Please submit your answers to my alternate e-mail (see business card). Post only number of characters you used in comments!

I’m neither Craig nor Mark. So do not expect t-shirts or iPods πŸ˜‰

Assigned Tags

      12 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Eddy De Clercq
      Eddy De Clercq
      Valery,

      I got 2 so far, unless I've made a mistake in my reasoning.

      I like these kind of quizes and micro code (see also Size does matter) a lot, so I some more in mind...

      Eddy

      Author's profile photo Former Member
      Former Member
      Eddy,

      As I replied in e-mail it doesn't handle zero, i.e. var s = "0" reported as not a number.

      However, it's even better then my original solution that fails on empty strings and a bit longer then yours (3 characters).

      Valery

      Author's profile photo Eddy De Clercq
      Eddy De Clercq
      Adding a little test would handle the zero problem
      if ( isNumber || s = "0" )
      Author's profile photo Eddy De Clercq
      Eddy De Clercq
      Oeps, typo. It should be off course
      if ( isNumber || s == "0" )
      Author's profile photo Former Member
      Former Member
      Oeps, underoptimized. It should be of course
      if ( isNumber || s == 0 )

      -- implicit type conversion saves 2 characters πŸ˜‰

      Valery

      Author's profile photo Former Member
      Former Member
      Well, after thorough testing, I have to clarify some restrictions:
      1. Trailing spaces in string are allowed
      2. Empty string is zero (0)

      VS

      Author's profile photo Eddy De Clercq
      Eddy De Clercq
      The official JS way is btw

      var s = "";
      if ( isNaN(s) )
      alert( "\"" + s + "\" is not a 'number' string" );
      else
      alert( "\"" + s + "\" is a 'number' string" );

      and saves even a line of code

      See also http://www.devguru.com/Technologies/ecmascript/quickref/isnan.html

      Author's profile photo Former Member
      Former Member
      Eddy,

      I just extract "test" code to separate variable for clarity. You may write as well:
      if (+s) {...}

      So there is no one-line-saving, actually.

      Yes, isNaN is standard built-in method that works exactly as required. Moreover, it is the only method that should be used in real life. When I see someone using clever hack like "+str" to check a number in real code, I just want to smack him. πŸ˜‰

      The only practical value of the quiz is interviewing. Interviewer may quickly distinguish between candidates depending on answers they provided. Just recall how many features are already outlined in your and Pran answers:
      1. implicit string conversion to number for arithmetic operations
      2. implicit string conversion to number for comparision (see my reply to Pran)
      3. implicit conversion of any type to boolean in conditions.

      Valery

      Author's profile photo Former Member
      Former Member
      You should have said something before hand I would have offered 25 bonus points for things like this πŸ™‚
      Author's profile photo Former Member
      Former Member
      -s
      fails with s=0

      s-s==0
      fails if s.trim() == ""

      s==s.match(/\d+/)
      Seems to work

      Whats the solution?

      Author's profile photo Former Member
      Former Member
      Pran,

      Eddy was the first who suggested this (via e-mail):
      var isNumber = -s;

      Actually, you are both "grumpy men" -- I told this already to Eddy. Why you prefer former above this:
      var isNumber = +s;

      Also valid (or suffer from same "zero-value" problem), but is far cry _positive_! ;))

      s-s==0 -- yep, works, but not that good
      My original was:
      s==s*1
      and my coworker suggested me
      s==s-0

      However, here variable "s" is repeated twice. Hmmm, not "pure" solution.

      s==s.match(/\d+/)
      isNaN(s)

      RegExp is longer then built-in method and doesn't handle float numbers.

      As I added in comments, leading/trailing spaces are ok, and empty string is equivalent for zero. The solution must handle zeros and any other integer / float numbers.

      So we have:
      var isNumber = -s (2 characters, but doesn't handle zero)
      var isNumber = s-s==0 (6 characters, all tests passed)

      There is one solution that involves 5 characters, and the best solution is 3 characters.

      Can you find it? πŸ˜‰

      Valery

      Author's profile photo Former Member
      Former Member
      After 3 days I guess it's ok to publish the final answer:
      //==========
      var isNumber = 1/s;
      //==========
      3 characters!

      1. If s is not a number string, then we get NaN as result. NaN used in conditions yields false.
      2. If string is a number not equals to zero, we get finite non-zero result. Finite non-zero number yields true in conditions.
      3. If string is zero (or empty string for this matter) we have division by zero. Division by zero yields Infinity (not an exception!). Infinity in conditions is treated as true value.

      Solution supports numbers like "-3.14", "5", "3E-3", "0xFF" -- i.e. everything that !isNaN(s) expression do.

      Howevere, I like very much solution provided by both Eddy & Pran: just 2 characters!

      Valery

      P.S. Pay attention -- this is _quiz question_. It may be useful in interviews, but not in application code. For your real-life scripts use isNaN(v) check, while it is explicit.