2

Given a string stored in a variable 'givenValue'. If it's all numbers, convert the string to number

(e.g. '11' to 11, 'a1' to 'a1')

and assign it to a variable 'value':

const value = givenValue - 0 === NaN ? givenValue : givenValue - 0;

But the output is not what I expected:

const givenValue = 'a1';
console.log(value); // NaN

const givenValue = '1';
console.log(value); // 1

Seems like the value of 'givenValue' is reassigned at the time of the 'if' condition being checked, or the condition check is not working.

0

5 Answers 5

3

You can use isNaN function to check something is NaN or not:

const givenValue = 'a1';
console.log(isNaN(givenValue) ? givenValue : +givenValue);

Also, if you want to check something is numeric or not before casting to a number, you can use isNaN function with isFinite function:

const givenValue = 'a1';

const value = !isNaN(parseFloat(givenValue)) && isFinite(givenValue) 
              ? givenValue : +givenValue;

console.log(value);
Sign up to request clarification or add additional context in comments.

Comments

3

Strings that aren't fully numbers but have numeric characters may well return a number other than NaN in many circumstances - see that link for a full description of how the algorithm works. Suffice to say, it's slightly complicated, and isn't what you're looking for. (eg, you'd want '123e456' to fail, but that'd actually give you Infinity instead. Whitespace will be permitted too.) (Also, a === NaN check will always return false, because NaN isn't equal to anything)

Instead, use a regular expression to check that the string contains only digits:

const value = /^\d+$/.test(givenValue) ? Number(givenValue) : givenValue;

If you want to include possible decimal amounts too, then add an optional group of . followed by digits:

const value = /^\d+(?:\.\d+)?$/.test(givenValue) ? Number(givenValue) : givenValue;
//                 ^^^^^^^^^^

4 Comments

Can you please explain me the ?: part in your pattern?
That's an optional group of . followed by digits. Eg, it'll match the .123 part of 1.123 - it matches a . followed by \d+, digits
Because I see that you have ? follows by the group (\.\d+), so I think we can remove it ?:. The last ? mean: everything inside the group can be zero or one time, right?
The ?: at the beginning of the group makes it non-capturing. Capturing groups (denoted with just plain parentheses) should be used only when you need to capture the value - otherwise, better to use a non-capturing group, with (?:, to indicate to both the reader and the engine that the matched subpattern doesn't need to be saved or considered later.
0

NaN doesn't equal itself. Try like this: givenValue - 0 !== givenValue - 0 ? givenValue : givenValue - 0.

Comments

0

In Javascript, NaN === NaN is alway false.

So you should use isNaN(givenValue - 0) rather than givenValue - 0 === NaN

console.log(NaN === NaN) // false
console.log(NaN == NaN) // false
console.log(isNaN(NaN)) // true

const fixedFunc = (givenValue) => isNaN(givenValue - 0) ? givenValue : givenValue - 0;

console.log(JSON.stringify({
  "fixedFunc('a1')": fixedFunc('a1'),
  "fixedFunc('1')": fixedFunc('1')
}))

Comments

-1

ONLY WORKS WITH NONZERO NUMBERS

A simpler method would be to use const value = givenValue - 0 || givenValue;

var givenValue = '1';
var value = givenValue - 0 || givenValue;
console.log(value);

givenValue = 'a1';
value = givenValue - 0 || givenValue;
console.log(value);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.