Convert whole string to integer in JavaScript

I recently came across a piece of code very similar to this:

var nHours = parseInt(txtHours); if( isNaN(nHours)) // Do something else // Do something else with the value 

The developer who wrote this code was impressed that nHours would be either an integer that exactly matches txtHours or NaN . There are several things in this assumption.

First, the developer to the left of the radix argument, which means entering "09" will result in a value of 0 instead of 9 . This problem can be solved by adding to it the same way:

 var nHours = parseInt(txtHours,10); if( isNaN(nHours)) // Do something else // Do something else with the value 

Further, entering "1.5" will result in a value of 1 instead of NaN , which does not correspond to the expected developer, since 1.5 not an integer. Similarly, a value of "1a" will result in a value of 1 instead of NaN .

All of these problems are somewhat understandable, as this is one of the most common examples of how to convert a string to an integer, and most places do not discuss these cases.

Anyway, it made me think that I don’t know any built-in way to get an integer like this. There is Number(txtHours) (or +txtHours ) that approaches, but accepts non-integer numbers and will treat null and "" as 0 instead of NaN .

To help the developer, I provided the following function:

 function ConvertToInteger(text) { var number = Math.floor(+text); return text && number == text ? number : NaN; } 

This seems to cover all of the above issues. Does anyone know something is wrong with this method or perhaps an easier way to get the same results?

+7
javascript string integer
source share
4 answers

Here is what I came up with:

 function integer(x) { if (typeof x !== "number" && typeof x !== "string" || x === "") { return NaN; } else { x = Number(x); return x === Math.floor(x) ? x : NaN; } } 

(Note: I updated this feature to maintain protection against white space lines. See below.)

The idea is to accept only arguments whose type is either a number or a string (but not an empty string value). It then converts to a number (if it is a string), and finally, its value is compared with the value of floor () to determine if the number is an integer or not.

 integer(); // NaN integer(""); // NaN integer(null); // NaN integer(true); // NaN integer(false); // NaN integer("1a"); // NaN integer("1.3"); // NaN integer(1.3); // NaN integer(7); // 7 

However, the NaN value here is “misused” because floats and strings representing floats lead to NaN, and this is technically incorrect.

Also note that due to the way strings are converted to numbers, the string argument may have trailing or leading white space or leading zeros:

 integer(" 3 "); // 3 integer("0003"); // 3 

Another approach ...

You can use regex if the input value is a string. This is a regular expression: /^\s*(\+|-)?\d+\s*$/ will match strings representing integers.

UPDATED FUNCTION!

 function integer(x) { if ( typeof x === "string" && /^\s*(\+|-)?\d+\s*$/.test(x) ) { x = Number(x); } if ( typeof x === "number" ) { return x === Math.floor(x) ? x : NaN; } return NaN; } 

This version of integer () is more restrictive since it only allows the use of strings that follow a specific pattern (which is checked using a regular expression). It gives the same results as another integer () function, except that it additionally ignores all white space lines (as indicated by @CMS).

Updated again!

I noticed @Zecc's answer and simplified the code a bit ... I think this works too:

 function integer(x) { if( /^\s*(\+|-)?\d+\s*$/.test(String(x)) ){ return parseInt(x, 10); } return Number.NaN; } 

This is probably not the fastest solution (in terms of performance), but I like its simplicity :)

+3
source share

Here is my attempt:

 function integer(x) { var n = parseFloat(x); // No need to check typeof x; parseFloat does it for us if(!isNaN(n) && /^\s*(\+|-)?\d+\s*$/.test(String(x))){ return n; } return Number.NaN; } 

I need to assign Šime Vidas for regular expression, although I will get there myself.

Change I did not know that there was a global NaN . I always used Number.NaN .
Live and learn.

+1
source share

My solution includes some cheap tricks. This is based on the fact that bit operators in Javascript convert their operands to integers.

I was not sure if strings representing integers should work, so here are two different solutions.

 function integer (number) { return ~~number == number ? ~~number : NaN; } function integer (number) { return ~~number === number ? ~~number : NaN; } 

The first will work with both whole integer lines and the second. The bitwise not (~) operator converts its operand to an integer. This method fails for integers that cannot be represented by the 32-bit representation of integers (-2147483647 .. 2147483647).

+1
source share

You can convert String to Integer first and then return to String again. Then check the matching of the first and second lines.

Edit : an example of what I meant:

 function cs (stringInt) { var trimmed = stringInt.trim(); // trim original string var num = parseInt(trimmed, 10); // convert string to integer newString = num + ""; // convert newly created integer back to string console.log(newString); // (works in at least Firefox and Chrome) check what new string like return (newString == trimmed); // if they are identical, you can be sure that original string is an integer } 

This function will return true if the string you put is really an integer. It can be changed if you do not want to trim. Using leading zeros will fail, but again, you can get rid of them in this function if you want. This way you don't have to bother with NaN or regular expression, you can easily check the validity of your string integer.

-one
source share