Please look at the following code. I can't get my values to add up. The digit just adds itself to the back of the string. Wonder any way to go about it.
$("a[name='older_post']").click(function(){
$("div.main_ads_div a[name='older_post']").remove().fadeOut();
var last_td_id=parseInt($("table.main_ads_table:last").find("td.load_ads:last").attr("id"),10);
alert(last_td_id); //OUTPUTS 38
$("div.main_ads_div").append('<table class="main_ads_table" col="7" row="7"><tr><td class="load_ads" id="'+last_td_id+1+'"></td><td class="load_ads" id="'+last_td_id+2+'"></td><td class="load_ads" id="'+last_td_id+3+'"></td><td class="load_ads priority" id="'+last_td_id+4+'"></td><td class="load_ads priority" id="'+last_td_id+5+'"></td><td class="load_ads" id="'+last_td_id+6+'"></td><td class="load_ads" id="'+last_td_id+7+'"></td><td class="load_ads" id="'+last_td_id+8+'"></td></tr></table>');
});
So what I'm trying to get here is for the each td that appends, I'm trying to get 39, 40, 41, 42... But I'm getting values such as 381, 382, 383,... etc etc.
Any help here appreciated.
Wrap the addition in parentheses:
... + (last_td_id + 7) + ...
You are concating string with number, enclose the addition in parentheses to perform arithmatic operation on it.
Change
+last_td_id+1+
To
+(last_td_id+1)+
The association of + is left to right and in the statement '....class="load_ads" id="'+last_td_id first concatenates the left hand string with number (last_td_id) and gives a string which again concatenates the incremental number like (2 or 3 ..) to previous string. Putting the parenthesis around the number makes its precedence high and the calucation is performed first and result is concatenated in the string.
The plus operator only performs mathematical addition only if both operands are numbers. If one of them is a string, it will perform string concatenation (and cast the 1 to "1").
Yet it is left associative, and you are not using parenthesis. So your expression is evaluated as
(((…('<…' + id) + 1) + '"…') + id) + 2) + …
and every single step yields a string. You will need to enforce the addition to be executed first by wrapping it in parenthesis, as others have already mentioned:
'<…' + (id + 1) + '"…' + (id + 2) + …
// evaluated as
(((…('<…' + (id + 1)) + '"…') + (id + 2)) + …
Using '+' in javascript always appends the variables/strings. Try something like this:
var c = (16 * 24) + 12;
d = c.toString();
Only then the var 'd' will give you the mathematical output
In your case, it could be
(last_td_id+4).toString(); and so on
Related
The following code snippet assigns some values by mixing parentheses and square brackets without any error, however most of the other combinations (e.g. parentheses inside square brackets) don't work at all.
var myItems = [];
myItems[5] = ("A1", "B1", ["C1","C2","C3"]);
When I print the values, they are exactly the same in two different browsers.
myItems[5]: C1,C2,C3
myItems[5][0]: C1
myItems[5][1]: C2
myItems[5][2]: C3
myItems[5][2][0]: C
myItems[5][2][1]: 3
myItems[5][2][2]: undefined
It seems that only the part inside square brackets is considered. Is this outcome defined by the JavaScript standard (ECMA-262)? Or is it just what the interpreter/engine (Chrome and Firefox in my case) did in the face of an illegal use?
var myItems = [];
//myItems[5] = ["A1", "B1", ["C1","C2","C3"]];
myItems[5] = ("A1", "B1", ["C1","C2","C3"]);
document.getElementById("demo").innerHTML =
"myItems[5]: " + myItems[5] + "<br/>" +
"myItems[5][0]: " + myItems[5][0] + "<br/>" +
"myItems[5][1]: " + myItems[5][1] + "<br/>" +
"myItems[5][2]: " + myItems[5][2] + "<br/>" +
"myItems[5][2][0]: " + myItems[5][2][0] + "<br/>" +
"myItems[5][2][1]: " + myItems[5][2][1] + "<br/>" +
"myItems[5][2][2]: " + myItems[5][2][2] + "<br/>" +
"";
<p id="demo"></p>
EDIT: I know the correct use of brackets (my fiddle already had it), but I'm asking if the outcome is deterministic at such a wrong use. Since the interpreters I've tried don't produce any error and give the same results, I want to know if these results are ensured by the standard and/or all the other interpreters will do the same.
From MDN on comma operator
The comma operator evaluates each of its operands (from left to right)
and returns the value of the last operand.
So
myItems[5] = ("A1", "B1", ["C1","C2","C3"]);
Turns to
myItems[5] = (["C1","C2","C3"]);
Now you've got yourself an array with 6 elements (5x undefined and the array of three strings you assigned at sixth position).
And it is exactly what you're getting printed out.
The comma operator , "evaluates each of its operands (from left to right) and returns the value of the last operand." (You can take that quote from Mozilla as gospel, or try to decipher what ECMA has to say on the matter.)
The grouping operator ( ) "controls the precedence of evaluation in expressions," according to Mozilla. (Obligatory link to ECMA.)
In this instance, the grouping operator does essentially nothing, since there is only one expression being grouped. So this is a simple comma-separated list of values, the last one of which is an array. This is what gets assigned.
The comma operator is often seen when assigning variables in bulk, e.g. var foo = 1, bar = 2, baz = 3; The spec states that even though only the last item is returned, each item must be evaluated "because it may have observable
side‑effects." In this most common of use cases, the variables each have values assigned to them.
This question already has answers here:
How to add two strings as if they were numbers? [duplicate]
(20 answers)
Closed 7 years ago.
I am trying to add the number mathematically, but it keeps adding the number after it.
It takes the id number (begen), then it gets the number inside another div (kacbegen).
var begen = $(this).attr('id');
var kacbegen = $("#math" + begen).text();
var toplam = (kacbegen + 1);
alert(toplam);
However, when doing the math (toplam), it alerts all the numbers.How to add the number mathematically ?
Convert it to number via adding a +:
var toplam = (+kacbegen + 1);
Unary plus (+)
The unary plus operator precedes its operand and evaluates to its operand but attempts to converts it into a number, if it isn't already.
It looks like you're working with Strings (and thus a + b is the concatenation operator) when you want to be working with Number (so x + y would be addition)
Perform your favorite way to cast String to Number, e.g. a unary +x
var kacbegen = +$("#math" + begen).text();
You need to use parseInt to convert kacbegen, which is a String instance, to a Number:
var begen = $(this).attr('id');
var kacbegen = $("#math" + begen).text();
var toplam = (parseInt(kacbegen) + 1);
alert(toplam);
The + operator, when used with a String on either side, will serve as a concatenation, calling Number.prototype.toString on 1.
You need to cast the contents to a number:
var contents = $("#math" + begen).text();
var kacbegen = parseFloat(contents);
You use kacbegen as a string. Please use as a integer use parseInt(kacbegen) + 1
I have the following:
var offset;
offset = localStorage.getItem('test.MenuList.Offset.' + examID + "." + level) || 0;
offset += 100;
When I use the debugger this offset now has 0100. I want it to add like a number not a string. How can I do this?
Please note I changed the question slightly because I realized I was getting the value from local storage. I assume this returns a string. But I am still not sure how to solve this.
The code you gave won't do that. I assume your value in your actual code is a numeric string. If so, the + will behave as a string concatenation operator, so you must convert the value to a number before using +.
You can do that with parseFloat().
var offset = localStorage.getItem('test.MenuList.Offset.' + examID + "." + level);
offset = parseFloat(offset) || 0;
Or in most cases, you can simply use the unary version of + to do the conversion.
offset = +offset || 0;
I am currently writing a JS rules engine which at one point needs to evaluate boolean expressions using the eval() function.
Firstly I construct an equation as such:
var equation = "relation.relatedTrigger.previousValue" + " " + relation.operator +
" " + "relation.value";
relation.relatedTrigger.previousValue is the value I want to compare.
relation.operator is the operator (either "==", "!=", <=, "<", ">", >=").
relation.value is the value I want to compare with.
I then simply pass this string to the eval function and it returns true or false as such:
return eval(equation);
This works absolutely fine (with words and numbers) or all of the operators except for >= and <=. E.g. When evaluating the equation:
relation.relatedTrigger.previousValue <= 100
It returns true when previousValue = 0,1,10,100 & all negative numbers but false for everything in between.
I would greatly appreciate the help of anyone to either answer my question or to help me find an alternative solution.
Regards,
Augier.
P.S. I don't need a speech on the insecurities of the eval() function. Any value given to relation.relatedTrigger.previousValue is predefined.
edit: Here is the full function:
function evaluateRelation(relation)
{
console.log("Evaluating relation")
var currentValue;
//if multiple values
if(relation.value.indexOf(";") != -1)
{
var values = relation.value.split(";");
for (x in values)
{
var equation = "relation.relatedTrigger.previousValue" + " " + relation.operator +
" " + "values[x]";
currentValue = eval(equation);
if (currentValue)
return true;
}
return false;
}
//if single value
else
{
//Evaluate the relation and get boolean
var equation = "relation.relatedTrigger.previousValue" + " " + relation.operator +
" " + "relation.value";
console.log("relation.relatedTrigger.previousValue " + relation.relatedTrigger.previousValue);
console.log(equation);
return eval(equation);
}
}
Answer: Provided by KennyTM below. A string comparison doesn't work. Converting to a numerical was needed.
You didn't show how relation.relatedTrigger.previousValue is obtained, but I guess the type of this variable is still a string. In this case, the right hand side will be treated as a string instead. A string comparison matches all characteristics you mentioned:
>>> '-213' <= '100'
true
>>> '0' <= '100'
true
>>> '1' <= '100'
true
>>> '2' <= '100'
false
>>> '10' <= '100'
true
>>> '13' <= '100'
false
You need to make sure relation.relatedTrigger.previousValue is a number. One solution is use the unary + operator in the comparison, e.g.
+relation.relatedTrigger.previousValue <= 100
This has nothing to do with eval. The problem is the overly liberal implicit conversion in Javascript.
Edit: By the way, instead of eval, you could use a dictionary of functions instead. This is faster and also safer. See http://jsperf.com/eval-vs-function-map.
var fmap = {
'>=': function(a, b) { return a >= b; },
...
};
fmap[relation.operator](+relation.relatedTrigger.previousValue,
+relation.value);
It is comparing strings not numbers.
Make sure that relation.relatedTrigger.previousValue and relation.value are numbers.
"11" > "100": Because 11 comes after 100 in alphabetical order.
11 < 100 in numeric order.
var relation = {'relatedTrigger':{'previousValue':"7"}, 'operator':'<=', 'value': "100"};
var equation = "parseFloat(relation.relatedTrigger.previousValue)" + " " + relation.operator +
" " + "parseFloat(relation.value)";
alert(equation + ", " + eval(equation));
This is effectively what you end up with and the extra step to ensure numeric value, not strings are passed seems to work.
This is all in the context of a larger program, so Im going to try keep it simple, showing the offending lines only. I have an array of values that are numbers in string form a la "84", "32", etc.
Yet THIS line
console.log(unsolved.length + " " + unsolved[0] + " " + parseInt(unsolved[0]) + " " + parseInt("84"));
prints:
4 "84" NaN 84
"84" is the array element Im trying to parseInt! Yet it won't work unless I take it out of the context of an array and have it explicitly written. What's going on?
You can try removing the quotations from the string to be processed using this function:
function stripAlphaChars(source) {
var out = source.replace(/[^0-9]/g, '');
return out;
}
Also you should explicitly specify that you want to parse a base 10 number:
parseInt(unsolved[0], 10);
parseInt would take everything from the start of its argument that looks like a number, and disregard the rest. In your case, the argument you're calling it with starts with ", so nothing looks like a number, and it tries to cast an empty string, which is really not a number.
You should make sure that the array element is indeed a string which is possible to parse to a number. Your array element doesn't contain the value '84', but actually the value '"84"' (a string containing a number encapsulated by ")
You'll want to remove the " from your array elements, possible like this:
function removeQuotationMarks(string) {
return (typeof string === 'string') ? string.replace(/"|'/g, '') : string;
}
unsolved = unsolved.map(removeQuotationMarks);
Now all the array elements should be ready to be parsed with parseInt(unsolved[x], 10)
First we need to replace " to ' in give data using Regex and replace and then we need to cast.
var i = 1;
var j = "22"
function stringToNumber(n) {
return (typeof n === 'string') ? parseInt(Number(n.replace(/"|'/g, ''))) : n;
}
console.log(stringToNumber(i)); // 1
console.log(stringToNumber(j)); // 22