I am trying to convert an array of numbers to an array of strings and get the first character in each element of the array. Tell me what I am doing wrong that I get "0" and not "-" in the last element?
function example
function invert(array) {
let q = array.map(i => i.toString()[0])
}
invert([-10,8,-2,-0])
result Array(4) [ "-", "8", "-", "0" ]
Per MDN's Number.toString docs:
Both 0 and -0 have "0" as their string representation.
If you want it to have a negative sign, you'll have to special case -0 (this can be harder than it seems).
Based on this answer Are +0 and -0 the same? you can use Object.is to check if a number is -0
function invert(array) {
return array.map(i => Object.is(i, -0) ? '-' : i.toString()[0])
}
console.log(invert([-10,8,-2,-0]))
Related
Javascript Code
I am concacting two variables and comparing with a string
Why the alert is true? Why it is not coercing??
var str1 = "2";
var str2 = "3";
var res = str1 + str2 // return 23
console.log(res) // 23
console.log("100") // 100
alert(res > "100") // alerts true instead of false
The value in res is a string. In strings "23" is greater than "100" (looking at the first character).
To further answer your question "why isn't javascript coercing" I'd like to quote a comment from James Thorpe
"Both sides are strings - there is nothing to coerce"
Here's a code example.
console.log (23 > "100") // false
console.log ("23" > "100") // true
First console.log compares number with string - javascript coerces.
Second console.log compares string with string - nothing to coerce
Alert is true because '23' is lexicographically greater than '100' ('2' > '1').
You can use parseInt to convert strings to numbers:
alert(parseInt(res) > 100);
Because you are comparing strings. "100" is lower then "23" because "1"<"2".
You should parse to int if you want numerical comparison, as shown in #jh314 answer.
You can temporarily change the string to their number representation i.e, 23 and 100 and use the comparison operator. Either prefix the values with + to change them to numeric value or use parseInt():
var str1 = "2";
var str2 = "3";
var res = str1 + str2 // return 23
console.log(res) // 23
console.log("100") // 100
alert(+res > +"100")
The value of res is "23" not 23. That means it's a string and therefore when you alert the comparison it compares the first digit of each, 2 > 1 which is true.
As for “why is it not coercing?” - because both operands are strings in both cases, and because both + and > are valid operations on strings.
(Using - (subtract) would cause implicit coercion to number because it doesn’t make sense for strings, but concatenation and addition use the same operator. Welcome to JavaScript!)
Your alert is comparing a string and a string.
Try: alert(res > 100)
I am trying to learn JavaScript but find it to be a bit confusing. I am trying to square every digit of a number
For example: run 9119 through the function, 811181 will come out, because 9^2 is 81 and 1^2 is 1.
My code:
function squareDigits(num){
return Math.pow(num[0],2) && Math.pow(num[1],2);
}
Correct code:
function squareDigits(num){
return Number(('' + num).split('').map(function (val) { return val * val;}).join(''));
}
I do not know why .map, .split, and .join was used to answer the question.
.split takes a string and splits it into an array based on the character(s) passed to it '' in this case.
So
("9119").split('') === ["9", "1", "1", "9"]
.map works like a for loop but takes a function as an argument. That function is applied to every member of the array.
So
["9", "1", "1", "9"].map(function(val) { return val * val;}) === ["81", "1", "1", "81"]
.join does the opposite of .split. It takes an Array and concatenates it into a string based on the character(s) passed to it.
So
["81", "1", "1", "81"].join('') === "811181"
Additionally, the && operator checks to see if the expressions on either side of it evaluate to true. If both expressions evaluate to true, only then will it return true. It always returns a Boolean though. I think you wanted to convert your values to string first using Number.toString() and then append them together using the + operator
return Math.pow(num[0],2).toString() + Math.pow(num[1],2).toString();
function squareDigits(num) {
// Convert the result to a number. "252525" -> 252525
return Number(
num.toString() // num === "555"
.split('') // ["5", "5", "5"]
.map(elem => elem * elem) "5" * "5" === 25 (Type coversion)
// Now we have [25, 25, 25]
.join('') // "252525"
);
}
squareDigits(555);
There are several methods of this, but the first that comes to mind is to pass the number as a string, split it, then parse the numbers, square them individually, make them strings, and paste them back together, it sounds complex but makes sense once you see it
//function takes number as an argument
function convertNumber(num){
//the toString method converts a number into a string
var number = num.toString();
//the split method splits the string into individual numbers
var arr = number.split("");
//this variable will hold the numbers that we square later
var squaredArr = [];
//the for loop iterates through everything in our array
for(var i=0; i<arr.length; i++){
//parseInt turns a string into a number
var int = parseInt(arr[i]);
//Math.pow raises integers to a given exponent, in this case 2
int = Math.pow(int, 2);
//we push the number we just made into our squared array as a string
squaredArr.push(int.toString());
}
//the function returns the numbers in the squared array after joining
//them together. You could also parseInt the array if you wanted, doing
//this as parseInt(squaredArr[0]); (this would be done after joining)
return squaredArr.join('');
}
Basically you need single digits for getting squared values.
You could take Array.from, which splits a string (which is a type with an implemented Symbol.iterator) into characters and uses an optional maping for the values.
function sqare(number) {
return +Array.from(number.toString(), v => v * v).join('');
}
console.log(sqare(9119));
try these code..
function squareDigits(n) {
return +(n.toString().split('').map(val => val * val).join(''));
}
console.log(squareDigits(4444));
here + sign is convert the string into an integer.
I don't understand why an empty array, or an array with only 1 "numerical" value can be used in certain calculations.
[] * [] === 0 //true
[2] * [2] === 4 //true
["2"] * ["2"] === 4 //true
However, it does not seem that is always the case with every operator.
[2] + [1] === 3 // false, actual result is "21"
[2] - [1] === 1 // true
I also checked these, and saw expected results:
[4] === "4" // false
[4] === 4 // false
In most cases, I would expect NaN in any of these mathematical operations. What is it about JavaScript arrays that allows this? Is it because the array toString method is being used somehow internally?
The arrays are coerced into strings, such that [] == "", [1] == "1", and [1, 2] == "1,2".
When you do certain mathematical operations on strings, they are coerced into Number types.
For example, when you do [2] * [2] it becomes "2" * "2" which becomes 2 * 2. You can even mix types and do [2] * 2 or "2" * [2].
When you try to use +, it attempts to concatenate the strings instead of coercing the strings to numbers. That's why "2" + "2", "2" + [2], and [2] + [2] each give you "22".
The same ol'problem of having + as string concatenation operator.
An array in Javascript is an Object. When you try to coerce objects into primitive values, there is an order to follow:
<obj>.toString()
<obj>.toNumber()
<obj>.toBoolean()
If you're using the * operator, coerce into string is not possible, so the interpreter goes to toNumber().
When you're using the + operator, the first attempt will be toString(). Since + is also the string concat operator, then the expression will be evaluated as an array.
Yeah, javascript can get ugly.
Edit:
Some further details can be found here.
In regards to +, + is a coercive operator on Strings, irrespective of it being the lvalue and rvalue, I'll quote the specification here:
If Type(lprim) is String or Type(rprim) is String, then Return the
String that is the result of concatenating ToString(lprim) followed by
ToString(rprim)
Multiplication however doesn't follow the same rules, it does however apply ToNumber, which as you've noticed, casts a [Number] to -> Number (+ does this as well, but it is a later step in the operator's definition)
Your last statement is answered by two rules of the SameValue algorithm defined in the spec, namely, if two values are of a different type, return false, alternatively, if two objects refer to the ptr, return true. Thus
a = [1];
b = [1];
a === b; // false
When you do mathematical operations on the arrays JavaScript converts them to the strings. But string doesn't have multiply operator and then JavaScript converts them to the numbers because you try to multiply them:
[] * [] === 0 // [] -> '' -> 0, result is 0 * 0
[2] * [2] === 4 // [2] -> '2' -> 2, result is 4 * 4
["2"] * ["2"] === 4 // ["2"] -> '2' -> 2, result is 4 * 4
String has a + operator:
[2] + [1] === 3 // '2' + '1', result is "21"
but doesn't have a - operator, therefore JavaScript converts them to the numbers too:
[2] - [1] === 1 // true, because they are numbers
=== it's strict equality, means that the objects being compared must have the same type.
[4] === "4" // false, you are comparing array with a string
[4] === 4 // false, you are comparing array with a number
Why in JavaScript "101" > "81" is false and "101" > "100" is true .I have encountered this issue when I do sorting on my extjs grid(where my column model is string).
Thats because "101" is string, if you make a conversion can get the result correct:
if(Number("101") > Number("81"))
{
...
}
Hope help you
You need to convert string to integer before comparison to get correct result.
use parseInt() function to convert string to integer.
if(parseInt("101") > parseInt("81"))
{
}
OR
You can use number() function - converts the object argument to a number that represents the object's value.
if(Number("101") > Number("81"))
{
}
Difference between parseInt() & Number() - both used to convert string to integer but difference --
parseInt() parses up to the first non-digit and returns whatever it had
parsed.
Number() - wants to convert the entire string into a number.
Ex.
parseInt("123hui") - 123
Number("123hui") - NaN
All of your values are string, that's why you're doing a string comparison. When comparing strings, you take letters one by one and the first difference determines the result.
In your case "101" and "81", you take "1" and "8" in the first step. It results in "1" < "8" which becomes the final result: "101" < "81".
In the other case "101" and "100", you take "1" and "1" in the first step and "0" and "0" in the second, which both are equal. The result is determined when comparing "1" and "0" because "1" > "0", that's why "101" > "100".
If the logic of the column is numeric, the model should be specified appropriately to number.
I store some parameters client-side in HTML and then need to compare them as integers. Unfortunately I have come across a serious bug that I cannot explain. The bug seems to be that my JS reads parameters as strings rather than integers, causing my integer comparisons to fail.
I have generated a small example of the error, which I also can't explain. The following returns 'true' when run:
console.log("2" > "10")
Parse the string into an integer using parseInt:
javascript:alert(parseInt("2", 10)>parseInt("10", 10))
Checking that strings are integers is separate to comparing if one is greater or lesser than another. You should always compare number with number and string with string as the algorithm for dealing with mixed types not easy to remember.
'00100' < '1' // true
as they are both strings so only the first zero of '00100' is compared to '1' and because it's charCode is lower, it evaluates as lower.
However:
'00100' < 1 // false
as the RHS is a number, the LHS is converted to number before the comparision.
A simple integer check is:
function isInt(n) {
return /^[+-]?\d+$/.test(n);
}
It doesn't matter if n is a number or integer, it will be converted to a string before the test.
If you really care about performance, then:
var isInt = (function() {
var re = /^[+-]?\d+$/;
return function(n) {
return re.test(n);
}
}());
Noting that numbers like 1.0 will return false. If you want to count such numbers as integers too, then:
var isInt = (function() {
var re = /^[+-]?\d+$/;
var re2 = /\.0+$/;
return function(n) {
return re.test((''+ n).replace(re2,''));
}
}());
Once that test is passed, converting to number for comparison can use a number of methods. I don't like parseInt() because it will truncate floats to make them look like ints, so all the following will be "equal":
parseInt(2.9) == parseInt('002',10) == parseInt('2wewe')
and so on.
Once numbers are tested as integers, you can use the unary + operator to convert them to numbers in the comparision:
if (isInt(a) && isInt(b)) {
if (+a < +b) {
// a and b are integers and a is less than b
}
}
Other methods are:
Number(a); // liked by some because it's clear what is happening
a * 1 // Not really obvious but it works, I don't like it
Comparing Numbers to String Equivalents Without Using parseInt
console.log(Number('2') > Number('10'));
console.log( ('2'/1) > ('10'/1) );
var item = { id: 998 }, id = '998';
var isEqual = (item.id.toString() === id.toString());
isEqual;
use parseInt and compare like below:
javascript:alert(parseInt("2")>parseInt("10"))
Always remember when we compare two strings.
the comparison happens on chacracter basis.
so '2' > '12' is true because the comparison will happen as
'2' > '1' and in alphabetical way '2' is always greater than '1' as unicode.
SO it will comeout true.
I hope this helps.
You can use Number() function also since it converts the object argument to a number that represents the object's value.
Eg: javascript:alert( Number("2") > Number("10"))
+ operator will coerce the string to a number.
console.log( +"2" > +"10" )
The answer is simple. Just divide string by 1.
Examples:
"2" > "10" - true
but
"2"/1 > "10"/1 - false
Also you can check if string value really is number:
!isNaN("1"/1) - true (number)
!isNaN("1a"/1) - false (string)
!isNaN("01"/1) - true (number)
!isNaN(" 1"/1) - true (number)
!isNaN(" 1abc"/1) - false (string)
But
!isNaN(""/1) - true (but string)
Solution
number !== "" && !isNaN(number/1)
The alert() wants to display a string, so it will interpret "2">"10" as a string.
Use the following:
var greater = parseInt("2") > parseInt("10");
alert("Is greater than? " + greater);
var less = parseInt("2") < parseInt("10");
alert("Is less than? " + less);