Javascript append string between math operations - javascript

items = 3;
$('#div').html(items + 1 + ' - ' + items + 3);
Trying to make #div display 4 - 6, but it instead shows 4 - 33. What am I missing?

As to why it happened:
first the parser reads items + 1, so fine and dandy, it's 4
then it concatenates with ' - ', so now you have 4 -
then it sees + items, at this moment, you are dealing with String, so it concatenates with 3 (as items is 3), so you have 4 - 3
then you have another concatenation with 3, but the left operand is a string, so the right operand is type casted into String as well, so you have 4 - 33
To achieve what you want, you need to enclose the inner operations:
$('#div').html((items + 1) + ' - ' + (items + 3));

Related

An assignment operator inside an assignment operator

'use strict';
let apples = '3';
let bananas = '4';
console.log(+apples + (apples = +bananas + 3));
The output is 10, unexpectedly. I thought it would be 14, and the compiler would think something like this
console.log(+apples + (apples = +bananas + 3));
console.log(+apples + (apples = 4 + 3));
console.log(+apples + (apples = 7)); //the variable 'apples' is going to be 7
console.log(+apples + 7); //'apples' now equals to 7
console.log(7 + 7);
console.log(14)
14
But on the step 4, 'apples' apparently equals to 3. Why isn't the output 14?
update: Can it be that there are parentheses around each operand, which are automatically added even though not directly written?
console.log((+apples) + ((apples = (+bananas) + (3)))); //since parentheses now have equal precedence(order), actions are done from left to right
console.log(3 + (apples = 4 + 3));
console.log(3 + (apples = 7)); //the variable 'apples' is going to be 7
console.log(3 + 7); //'apples' now equals to 7
console.log(3 + 7);
console.log(10)
10
That would, I think, logically explain why there is 10 instead of 14.
Sorry for clumsy code. I was just doing some practice after reading about operators in js.
On step 4, value of apples isn't 7 because the expression in your code example is evaluated from left to right.
So the following expression:
+apples + (apples = +bananas + 3)
is evaluated as:
Coerce the value of apples to a number
3 + (apples = +bananas + 3)
Coerce the value of bananas to a number
3 + (apples = 4 + 3)
Add 4 + 3 and assign the result of addition to apples
3 + (apples = 7)
(apples = 7) - value of this expression is 7
3 + 7
Final result = 10.

Print out math expression contained within variable

not really sure this is possible, cant seem to find any answers that cover it.
Ive found questions on running a math expression that's given as a string and they do the opposite of what im looking for.
basically im debugging my code and want to print out what the expression is to the console. There are currently 30 calculations in various expressions that run each time the code executes and the number is growing.
EG:
var equation = (1 + 5) * (21 x 7);
Ive simplified it as there are variables that are actually parsed for the output.
I want to out put the expression as a string running the calculation but also keep the calculation running for the application.
I am currently concatenating strings and its tedious work so I hoped there might be a better solution than this: as you should see, i do need the variables to work as expected but not the whole expression, thus giving the simplified more readable result above.
This works with varuns answer but not in my case see update below:
var printout = '(' +var1+ ' + ' +var2+ ') * (' +var3+ ' * ' +var4+ ')';
Update based upon Varun's Answer & Comments below it:
var array = [1, 5, 21, 7];
var printout = '(' +array[0]+ ' + ' +array[1]+ ') * (' +array[2]+ ' * ' +array[0]+ ')';
I guess below is the code you are looking for
var eq = `(1 + 5) * (21 * 7)`;
console.log( eq + ' = ' + eval(eq) )
You can also enhance it like this for more dynamic content
var array = [1, 5, 21, 7];
var inp1 = array[0]
var inp2 = array[1]
var inp3 = array[2]
var inp4 = array[3]
var addOperand = "+"
var multiplyOperand = "*"
var eq = `(${inp1} ${addOperand} ${inp2}) ${multiplyOperand} (${inp3} ${multiplyOperand} ${inp4})`;
console.log( eq + ' = ' + eval(eq) )
Since you are using arrays, this is seems scalable and efficient
var array = ['(',1, '+', 5,')', '*','(', 21,'*', 7,')'];
eq = array.join(' ')
console.log( eq + ' = ' + eval(eq) )
Could be more generic but not sure if you need that much only for testing,
here your equation can be any string.
lineNo is the lineNo of your equation inside the function
function calculate(x, y) {
var equation = (x + 5) * (y * 7);
let lineNo = 1
console.log(arguments.callee.toString().split('\n\t')[lineNo].replace(/x/g, x).replace(/y/g, y))
}
calculate(3, 4)

Largest Number ( javascript ) explanation

I was working on leetcode question and come across this question and saw an answer online.
According the MDN, we should an inner function sort(function(a,b) return a + b) to sort an array properly.
Can someone explain how does the closure works and further explain the following codes?
(I don't quite understanding the sequence of how the comparison is done)
/*Given a list of non negative integers, arrange them such that they form the largest number.
For example, given [3, 30, 34, 5, 9], the largest formed number is 9534330.
Note: The result may be very large, so you need to return a string instead of an integer.*/
var largestNumber = function(nums) {
return nums.sort(function (a,b){
return (b + '' + a) - (a + '' + b);
}).join('').replace(/^0*/,'') || '0';
};
var nums= [3, 30, 34, 5, 9]
console.log(largestNumber(nums));
What this sort is basically doing is for each element in the array a and b. Check which way the numbers would be high based on how they would be ordered. For example, if a = 30 and b = 5. Then:
(b + '' + a) - (a + '' + b)
530 - 305
225
Since this is a positive number it means b would be the left of of a in the final array (string).
So notice that in the example data [3, 30, 34, 5, 9], the element 9 compared to any other element would result in 9 being on the left (meaning it's the lowest item in the array). Here is a snippet example of each comparison done with some extra console information (to show how each comparison is being done and the result, notice that 9 was always lower compared to each element. Then the next number 5 is lower than everything but 9):
var largestNumber = function(nums) {
return nums.sort(function (a,b){
var priority = (b + '' + a) - (a + '' + b)
console.log((b + '' + a) + " - " + (a + '' + b) + " => " + (priority));
if(priority > 0) console.log(a + " > " + b);
else console.log(a + " < " + b);
return (b + '' + a) - (a + '' + b);
}).join('').replace(/^0*/,'') || '0';
};
var nums= [3, 30, 34, 5, 9]
console.log(largestNumber(nums));
The snipped you presented is basically a code that builds the largest possible "number" out of the elements of an array.
Lets imagine we have the following input: [3, 30, 34, 5, 9]
First of all, the sort is taking a function as parameter. Its job is to sort the nums in descending lexicographic order (so a 34 would be lesser than a 5, because 3 is lesser than 5). It does that by comparing the values of the strings composed by the "ab" and "ba", so if "ba" - "ab" is a negative value, it will assume that 'a' is lesser than 'b', and so on.
At this step you have: [9,5,34,3,30]
After the sorting takes place, it invokes the join() function with '' as parameter, which means it will join the elements into a string, separating each element with the given paramenter, which is no separation at all.
At this step you have: "9534330"
Then, you have a call to the replace function, which will look for a certain pattern and replace it by the given second parameter. The first parameter in this case is a regular expression, which will match each string with '0' at the beginning of it and that contain zero or more occurences of '0'.
(Reference to Regular expressions: http://www.w3schools.com/js/js_regexp.asp)
At this step you still have: "9534330"
Finally, at the end of the return expression there is an || '0', which basically means that it will return '0' in case the first part of the return expression is false, either by wrong or missing input.

Why does parseInt('dsff66',16) return 13?

today I stumbled on a strange (in my opinion) case in JavaScript. I passed a non-hexadecimal string to the parseInt function with the base of 16 and...I got the result.
I would expect the function to throw some kind of exception or at least return NaN, but it succeeded parsing it and returned an int.
My call was:
var parsed = parseInt('dsff66', 16); // note the 's' in the first argument
document.write(parsed);
and the result was: 13.
I noticed that it "stops" parsing with the first character that doesn't belong to the numeral system specified in the 2nd argument, so calling parseInt('fg',16) I would get 15 as a result.
In my opinion, it should return NaN. Can anyone explain to me why it doesn't? Why would anyone want this function to behave like this (return an integer even if it isn't the precise representation of the string passed) ?
parseInt reads input until it encounters an invalid character, and then uses whatever valid input it read prior to that invalid character. Consider:
parseInt("17days", 10);
This will use the input 17 and omit everything after the invalid d.
From the ECMAScript specification:
If [input string] S contains any character that is not a radix-R digit, then let Z [the string to be integer-ified] be the substring of S consisting of all characters before the first such character; otherwise, let Z be S.
In your example, s is an invalid base-16 character, so parseInt uses only the leading d.
As for why this behavior was included: there's no way to know for sure, but this is quite likely an attempt to reproduce the behavior of strtol (string to long) from C's standard library. From the strtol(3) man page:
...the string is converted to a long int value in the obvious manner, stopping at the first character which is not a valid digit in the given base.
This connection is further supported (to some degree) by the fact that both parseInt and strtol are specified to ignore leading whitespace, and they can both accept a leading 0x for hexadecimal values.
Why would anyone want this function to behave like this (return an integer even if it isn't the precise representation of the string passed)?
Because most of the time (by far) you're working with base 10 numbers, and in that case JS can just cast - not parse - the string to a number. (edit: Apparently not just base-10; see update below.)
Since JS is dynamically typed, some strings work just fine as numbers without any work on your part. For instance:
"21" / 3; // => 7
"12.4" / 4; // => 3.1
No need for parseInt there, because "21" and "12.4" are essentially numbers already. If, however the string was "12.4xyz" then you would indeed get NaN when dividing, since that is decidedly not a number and can't be implicitly cast or coerced to one.
You can also explicitly "cast" a string to number with Number(someString). While it too only supports base 10, it will indeed return NaN for invalid strings.
So because JS already has implicit and explicit type casting/conversion/coercion, parseInt's role isn't to be a yet another type casting function.
parseInt's role is instead to be, well, a parsing function. A function that tries its best to make sense of its input, returning what it can. It's for when you have a string you can't just cast because it's not quite perfectly numeric. (And, like JS's basic syntax, it's reminiscent of C, as apsillers' answer explained nicely.)
And since it's a parser, not a casting function, it's got the additional feature of being able to handle other bases than 10.
Now, you might ask why there isn't a strict casting function that handles non-base-10 numbers, and would complain like you want, but... hey, there just isn't. JS's designers just decided that parseInt would suffice, because, again, 0x63 percent of the time, you're dealing with base 10.
Closest you can get to "casting" is probably something horribly hacky like:
var hexString = "dsff66";
var number = eval("0x" + hexString); // attempt to interpret as a hexadecimal literal
which'll throw a SyntaxError because 0xdsff66 isn't a valid hex literal.
Update: As Lekensteyn points out in the comments, JS appears to properly cast 0x-prefixed hexadecimal strings too. I didn't know this, but indeed this seems to work:
1 * "0xd0ff66"; // => 13696870
1 * "0xdsff66"; // => NaN
which makes it the simplest way to cast a hex string to a number - and get NaN if it can't be properly represented.
Same behavior applies to Number(), e.g Number("0xd0ff66") returns an integer, and Number("0xdsff66") returns NaN.
(/update)
Alternatively, you can check the string beforehand and return NaN if needed:
function hexToNumber(string) {
if( !/^(0x)?[0-9a-f]+$/i.test(string) ) return Number.NaN;
return parseInt(string, 16);
}
In this particular case parseInt() interpret letter from "A" to "F" as hexadecimal and parse those to decimal numbers. That means d will return 13.
What parseInt() does
parseInt("string", radix) interpret numbers and letters in the string as hexadecimal (it depend on the radix) to number.
parseInt() only parse number or letter as hexadecimal from the beginning of the string until invalid character as hexadecimal.
If parseInt() can't find any number or letter as hexadecimal at the beginning of the string parseInt() will return NaN.
If the radix is not defined, the radix is 10.
If the string begin with "0x", the radix is 16.
If the radix defined 0, the radix is 10.
If the radix is 1, parseInt() return NaN.
If the radix is 2, parseInt() only parse "0" and "1".
If the radix is 3 , parseInt() only parse "0", "1", and "2". And so on.
parseInt() parse "0" to 0 if there is no number follows it as the result and remove 0 if there is number follows it. e.g. "0" return 0 and "01" return 1.
If the radix is 11, parseInt() only parse string that begins with number from "0" to "9" and/or letter "A".
If the radix is 12, parseInt only parse string that begins with number from "0" to "9" and/or letter "A" and "B", and so on.
the maximum radix is 36, it will parse string that begins with number from "0" to "9" and/or letter from "A" to "Z".
If the characters interpreted as hexadecimal more than one, every characters will has different value, though those characters are the same character. e.g. parseInt("AA", 11) the first "A" has different value with the second "A".
Different radix will return different number though the strings is the same string.
See it in action
document.body.innerHTML = "<b>What parseInt() does</b><br>" +
"parseInt('9') = " + parseInt('9') + "<br>" +
"parseInt('0129ABZ', 0) = " + parseInt('0129ABZ', 0) + "<br>" +
"parseInt('0', 1) = " + parseInt('0', 1) + "<br>" +
"parseInt('0', 2) = " + parseInt('0', 2) + "<br>" +
"parseInt('10', 2) = " + parseInt('10', 2) + "<br>" +
"parseInt('01', 2) = " + parseInt('01', 2) + "<br>" +
"parseInt('1', 2) = " + parseInt('1', 2) + "<br>" +
"parseInt('A', 10) = " + parseInt('A', 10) + "<br>" +
"parseInt('A', 11) = " + parseInt('A', 11) + "<br>" +
"parseInt('Z', 36) = " + parseInt('Z', 36) + "<br><br>" +
"<b>The value:</b><br>" +
"parseInt('A', 11) = " + parseInt('A', 11) + "<br>" +
"parseInt('A', 12) = " + parseInt('A', 12) + "<br>" +
"parseInt('A', 13) = " + parseInt('A', 13) + "<br>" +
"parseInt('AA', 11) = " + parseInt('AA', 11) + " = 100 + 20" + "<br>" +
"parseInt('AA', 12) = " + parseInt('AA', 12) + " = 100 + 30" + "<br>" +
"parseInt('AA', 13) = " + parseInt('AA', 13) + " = 100 + 40" + "<br>" +
"parseInt('AAA', 11) = " + parseInt('AAA', 11) + " = 1000 + 300 + 30" + "<br>" +
"parseInt('AAA', 12) = " + parseInt('AAA', 12) + " = 1000 + 500 + 70" + "<br>" +
"parseInt('AAA', 13) = " + parseInt('AAA', 13) + " = 1000 + 700 + 130" + "<br>" +
"parseInt('AAA', 14) = " + parseInt('AAA', 14) + " = 1000 + 900 + 210" + "<br>" +
"parseInt('AAA', 15) = " + parseInt('AAA', 15) + " = 1000 + 1100 + 310";
For radices above 10, the letters of the alphabet indicate numerals greater than 9. For example, for hexadecimal numbers (base 16), A through F are used.
In your string dsff66, d is a hexadecimal character(even though the string is non hex) which fits the radix type and is equivalent to number 13. It stops parsing after that since next character is not hexadecimal hence the result.

Surprising simple operation results

In JavaScript, I tried executing the below statements
var x = 1+"2"-3; //Anser is 9.
var y = 1-"2"+4 //Anser is 3.
For such operations, what is converted to what?
I guess 1+"2" = 12(number) and then 12-3?
- converts the both operands to numbers. But if either operand to + is a string, the other is converted to string and it's a concatenation. Like "Hi, " + "how are you?" = "Hi, how are you?" So your answers are correct.
var x = 1+"2"-3;
// concats the string as 12 and then subtracts...
12 - 3 = 9
var y = 1-"2"+4
// converts to numbers and subtracts, making -1 and then adds 4 giving out 3
-1 + 4 = 3
This was the process.
Scenario I
Step 1:
1 + "2" => "12" //concatenation happened
Step 2
"12" - 3 => 9 //String widens to number since we are using - symbol here.
Scenario II
Step 1:
1 - "2" => -1 //String widens to number since we are using - symbol here.
Step 2:
-1 + 4 => 3 //Normal addition happens

Categories