An array shows 3 numbers randomly, and I had to write a code that sums the 3 numbers, but the array has a trick to sometimes show a string:
[96, ".!asd", 182]
["##$%", 5, 43]
[64, "bd", 48]
I would like to use an "if" that would return "not valid" if there's a string in the array.
if (...){
return not valid
}
Please, if there's a way to identify any string, could you tell me the code?
You can use Array.prototype.some() to see if your array contains NaN's
var x = [96, ".!asd", 182]
var y = [96, 1000, 182]
console.log(x.some(isNaN))
console.log(y.some(isNaN))
You should use the isNaN function as it is explained here : Is there a (built-in) way in JavaScript to check if a string is a valid number?
isNaN(123) // false
isNaN('123') // false
isNaN('1e10000') // false (This translates to Infinity, which is a number)
isNaN('foo') // true
isNaN('10px') // true
You can use isNaN to determine if a stirng is a number
isNaN('123') //false
isNaN('Hello') //true
Use the object Number:
if (Number.isNaN(+element_in_array)) return "Not Valid!!"
function sum(array) {
if (array.some((n) => Number.isNaN(+n))) {
return "Invalid data, at least one element is not a number.";
}
return array.reduce((a, n) => a + Number(n), 0);
}
console.log(sum([96, ".!asd", 182]))
console.log(sum(["##$%", 5, 43]))
console.log(sum([64, "bd", 48]))
console.log(sum([64, 44, 48]))
You could use NaN to determine if all elements are numbers by using an unary plus to convert the string to number. If succeed, you get a number for summing, if not then NaN is returned and summed. A single NaN spoils the result and the result is NaN.
function not(fn) {
return function (v) {
return !fn(v);
};
}
function sum(array) {
return array.reduce((a, b) => +a + +b);
}
console.log([[96, ".!asd", 182], ["##$%", 5, 43], [64, "bd", 48], [2, 3, 5]].map(sum).filter(not(isNaN)));
try using typeof to validate wether or not you are dealing with a string.mdn typeof
You can use if type(x) == str to check if a variable x is of type String. It is a built-in function. Please refer to official python documentation to know more.
https://docs.python.org/3/library/functions.html#type
Related
Index 28:
How do I remove this "NaN" value. Cant use isNaN because I want strings and numbers. But not NaN
Tried:
typeof value === 'undefined'
value == null
No success.
You can test for NaN specifically by using Number.isNaN, which is subtly different from plain isNaN: It only returns true if its argument is a number (whose value is NaN). In other words, it won't try to coerce strings and other values to numbers.
Demo:
const values = [
12,
NaN,
"hello",
{ foo: "bar" },
NaN,
null,
undefined,
-3.14,
];
const filtered = values.filter(x => !Number.isNaN(x));
console.log(filtered);
Number.isNaN is new in ECMAScript 6. It is supported by every browser except Internet Explorer. In case you need to support IE, here's a simple workaround:
if (!Number.isNaN) {
Number.isNaN = function (x) { return x !== x; };
}
you can use typeof (to check that's a number) in combination with isNaN
Note that typeof NaN returns "number"
typeof x === "number" && isNaN(x)
Another solution is to use Number.isNaN which will not trying to convert the parameter into a number. So it will return true only when the parameter is NaN
You should be able to use Number.isNaN
console.log([1, "foo", NaN, "bar"].filter((x) => !Number.isNaN(x)))
I’ve seen this comparison check, not sure if you could make it work for you.
var nanValue = NaN;
if(nanValue !== nanValue) // Returns true!
alert('nanValue is NaN');
How do you determine if a string represents a number?
The straightforward and potentially naive way is this:
function is_number(my_str) {
return !isNaN(parseInt(my_str));
}
However, the above does not work. Notice that the following all return true:
is_number("3, 4, 5");
is_number("3, (123)");
is_number("3, 123)");
is_number("3, (123) (and foo bar)");
is_number("3 apples and 2 oranges");
The issue is that parseInt seems to only look at the first word. Any idea on a more comprehensive solution here?
You can use Number().
parseInt and parseFloat converts String to Number if first character is a number. But Number() checks for whole String.Number return NaN if whole string is not number
function is_number(my_str) {
return !isNaN(Number(my_str)) && Boolean(my_str) || my_str == 0;
}
console.log(is_number("3, 4, 5"));
console.log(is_number("3, (123)"));
console.log(is_number("3, 123)"));
console.log(is_number("3, (123) (and foo bar)"));
console.log(is_number("3 apples and 2 oranges"));
console.log(is_number(null));
console.log(is_number(undefined));
console.log(is_number(0));
console.log(is_number('0'));
All you need is Number
console.log(Number("3, 4, 5") || false)
console.log(Number("3, (123)") || false)
console.log(Number("3, 123)") || false)
console.log(Number('123') || false)
Here's my regular-expression based effort:
function isNumber (string) {
return /^-?[0-9]+(?:\.[0-9]+)?(?:[eE][-+]?[0-9]+)?$/.test(string);
}
Includes support for leading sign, decimal places and exponent.
If it returns true, the string can be converted to a number using JSON.parse:
function isNumber (string) {
return /^-?[0-9]+(?:\.[0-9]+)?(?:[eE][-+]?[0-9]+)?$/.test(string);
}
function convertNumber (string) {
if (isNumber(string)) {
return JSON.parse(string);
}
}
[
'0',
'1.2',
'-3.4',
'5.6789e100',
'0.1e-100',
'0.1e+100',
].forEach(string => {
console.log(`isNumber('${string}'):`, isNumber(string));
console.log(`typeof convertNumber('${string}'):`, typeof convertNumber(string));
});
From the Mozilla Developer Network:
[1,4,9].map(Math.sqrt)
will yield:
[1,2,3]
Why then does this:
['1','2','3'].map(parseInt)
yield this:
[1, NaN, NaN]
I have tested in Firefox 3.0.1 and Chrome 0.3 and just as a disclaimer, I know this is not cross-browser functionality (no IE).
I found out that the following will accomplish the desired effect. However, it still doesn’t explain the errant behavior of parseInt.
['1','2','3'].map(function(i){return +i;}) // returns [1,2,3]
The callback function in Array.map has three parameters:
From the same Mozilla page that you linked to:
callback is invoked with three arguments: the value of the element, the index of the element, and the Array object being traversed."
So if you call a function parseInt which actually expects two arguments, the second argument will be the index of the element.
In this case, you ended up calling parseInt with radix 0, 1 and 2 in turn. The first is the same as not supplying the parameter, so it defaulted based on the input (base 10, in this case). Base 1 is an impossible number base, and 3 is not a valid number in base 2:
parseInt('1', 0); // OK - gives 1
parseInt('2', 1); // FAIL - 1 isn't a legal radix
parseInt('3', 2); // FAIL - 3 isn't legal in base 2
So in this case, you need the wrapper function:
['1','2','3'].map(function(num) { return parseInt(num, 10); });
or with ES2015+ syntax:
['1','2','3'].map(num => parseInt(num, 10));
(In both cases, it's best to explicitly supply a radix to parseInt as shown, because otherwise it guesses the radix based on the input. In some older browsers, a leading 0 caused it to guess octal, which tended to be problematic. It will still guess hex if the string starts with 0x.)
map is passing along a 2nd argument, which is (in many of the cases) messing up parseInt's radix parameter.
If you're using underscore you can do:
['10','1','100'].map(_.partial(parseInt, _, 10))
Or without underscore:
['10','1','100'].map(function(x) { return parseInt(x, 10); });
You could solve this problem using Number as iteratee function:
var a = ['0', '1', '2', '10', '15', '57'].map(Number);
console.log(a);
Without the new operator, Number can be used to perform type conversion. However, it differs from parseInt: it doesn't parse the string and returns NaN if the number cannot be converted. For instance:
console.log(parseInt("19asdf"));
console.log(Number("19asf"));
I'm going to wager that it's something funky going on with the parseInt's 2nd parameter, the radix. Why it is breaking with the use of Array.map and not when you call it directly, I do not know.
// Works fine
parseInt( 4 );
parseInt( 9 );
// Breaks! Why?
[1,4,9].map( parseInt );
// Fixes the problem
[1,4,9].map( function( num ){ return parseInt( num, 10 ) } );
You can use arrow function ES2015/ES6 and just pass number to the parseInt. Default value for radix will be 10
[10, 20, 30].map(x => parseInt(x))
Or you can explicitly specify radix for better readability of your code.
[10, 20, 30].map(x => parseInt(x, 10))
In example above radix explicitly set to 10
another (working) quick fix :
var parseInt10 = function(x){return parseInt(x, 10);}
['0', '1', '2', '10', '15', '57'].map(parseInt10);
//[0, 1, 2, 10, 15, 57]
You can solve that issue like this:
array.map(x => parseInt(x))
Example:
var arr = ["3", "5", "7"];
console.log(
arr.map(x => parseInt(x))
);
parseInt IMHO should be avoided for this very reason. You can wrap it to make it more safe in these contexts like this:
const safe = {
parseInt: (s, opt) => {
const { radix = 10 } = opt ? opt : {};
return parseInt(s, radix);
}
}
console.log( ['1','2','3'].map(safe.parseInt) );
console.log(
['1', '10', '11'].map(e => safe.parseInt(e, { radix: 2 }))
);
lodash/fp caps iteratee arguments to 1 by default to avoid these gotchas. Personally I have found these workarounds to create as many bugs as they avoid. Blacklisting parseInt in favor of a safer implementation is, I think, a better approach.
From the Mozilla Developer Network:
[1,4,9].map(Math.sqrt)
will yield:
[1,2,3]
Why then does this:
['1','2','3'].map(parseInt)
yield this:
[1, NaN, NaN]
I have tested in Firefox 3.0.1 and Chrome 0.3 and just as a disclaimer, I know this is not cross-browser functionality (no IE).
I found out that the following will accomplish the desired effect. However, it still doesn’t explain the errant behavior of parseInt.
['1','2','3'].map(function(i){return +i;}) // returns [1,2,3]
The callback function in Array.map has three parameters:
From the same Mozilla page that you linked to:
callback is invoked with three arguments: the value of the element, the index of the element, and the Array object being traversed."
So if you call a function parseInt which actually expects two arguments, the second argument will be the index of the element.
In this case, you ended up calling parseInt with radix 0, 1 and 2 in turn. The first is the same as not supplying the parameter, so it defaulted based on the input (base 10, in this case). Base 1 is an impossible number base, and 3 is not a valid number in base 2:
parseInt('1', 0); // OK - gives 1
parseInt('2', 1); // FAIL - 1 isn't a legal radix
parseInt('3', 2); // FAIL - 3 isn't legal in base 2
So in this case, you need the wrapper function:
['1','2','3'].map(function(num) { return parseInt(num, 10); });
or with ES2015+ syntax:
['1','2','3'].map(num => parseInt(num, 10));
(In both cases, it's best to explicitly supply a radix to parseInt as shown, because otherwise it guesses the radix based on the input. In some older browsers, a leading 0 caused it to guess octal, which tended to be problematic. It will still guess hex if the string starts with 0x.)
map is passing along a 2nd argument, which is (in many of the cases) messing up parseInt's radix parameter.
If you're using underscore you can do:
['10','1','100'].map(_.partial(parseInt, _, 10))
Or without underscore:
['10','1','100'].map(function(x) { return parseInt(x, 10); });
You could solve this problem using Number as iteratee function:
var a = ['0', '1', '2', '10', '15', '57'].map(Number);
console.log(a);
Without the new operator, Number can be used to perform type conversion. However, it differs from parseInt: it doesn't parse the string and returns NaN if the number cannot be converted. For instance:
console.log(parseInt("19asdf"));
console.log(Number("19asf"));
I'm going to wager that it's something funky going on with the parseInt's 2nd parameter, the radix. Why it is breaking with the use of Array.map and not when you call it directly, I do not know.
// Works fine
parseInt( 4 );
parseInt( 9 );
// Breaks! Why?
[1,4,9].map( parseInt );
// Fixes the problem
[1,4,9].map( function( num ){ return parseInt( num, 10 ) } );
You can use arrow function ES2015/ES6 and just pass number to the parseInt. Default value for radix will be 10
[10, 20, 30].map(x => parseInt(x))
Or you can explicitly specify radix for better readability of your code.
[10, 20, 30].map(x => parseInt(x, 10))
In example above radix explicitly set to 10
another (working) quick fix :
var parseInt10 = function(x){return parseInt(x, 10);}
['0', '1', '2', '10', '15', '57'].map(parseInt10);
//[0, 1, 2, 10, 15, 57]
You can solve that issue like this:
array.map(x => parseInt(x))
Example:
var arr = ["3", "5", "7"];
console.log(
arr.map(x => parseInt(x))
);
parseInt IMHO should be avoided for this very reason. You can wrap it to make it more safe in these contexts like this:
const safe = {
parseInt: (s, opt) => {
const { radix = 10 } = opt ? opt : {};
return parseInt(s, radix);
}
}
console.log( ['1','2','3'].map(safe.parseInt) );
console.log(
['1', '10', '11'].map(e => safe.parseInt(e, { radix: 2 }))
);
lodash/fp caps iteratee arguments to 1 by default to avoid these gotchas. Personally I have found these workarounds to create as many bugs as they avoid. Blacklisting parseInt in favor of a safer implementation is, I think, a better approach.
How can you find the last occurrence of a non-zero digit in a number/string in Javascript? With that, we will be able to split a zero-padded number into the actual number and its zero padding. Any JS/Node library can be used.
Tried using .lastIndexOf() but didn't find a way to define a non-zero digit.
Input
1.23400
1.00050
1.03456
Output
['1.234', '00']
['1.0005', '0']
['1.03456']
Use a regex :
/^([0-9]+\.?[0-9]*?)(0*)$/
/^([0-9]+\.?[0-9]*?)(0*)$/.exec('1.23400'); // return ["1.23400", "1.234", "00"]
/^([0-9]+\.?[0-9]*?)(0*)$/.exec('1.03456'); // return ["1.03456", "1.03456", ""]
You can use the parseFloat too if you juste interest by getting the significative part of the number.
parseFloat('1.23400') // return 1.234
Try this :
'1.23400'.match(/^.*?(?=0*$)|0+$/g)
// ^.*?(?=0*$) : everything before zero or more trailing zeros
// 0+$ : one or more trailing zeros
Try this:
function lastIndexOfDigit(str) {
var last_indices = [];
[1, 2, 3, 4, 5, 6, 7, 8, 9].map(function (digit) {
last_indices.push(str.lastIndexOf(digit));
});
var indices = last_indices.sort(function (a, b) {
return a - b;
});
return indices[indices.length - 1];
}