Why am I getting weird increments in my for loop? - javascript

I have been testing ways to check individual characters in a string for a numeric value. I set up a for loop that goes through them, but when I'm logging it to the console, I get a weird response:
isNumeric: function(n){
for(var i = 0; i < n.length; i++){
console.log("Looping " + i+1);
}
},
So I passed in the value "10" to test it. I get a weird response when I call the function. I get two logs onto the console (like expected), but it says
Looping 01
Looping 11
What is going on here? I didn't think that I was concating strings here, but for some reason it thinks I am? I declared i as an integer var i = 0; and when you increment it by one, what is it doing?
The only other thing I think it must be doing is logging something else appended to Looping 0 and Looping 1, but I don't think that's the case.
If anyone can please help, this is really bugging me and I can't seem to fix it.
Thanks in advance.

+ is left-to-right associative. The expression is evaluated as
('Looping ' + i) + 1
Is it clearer now why string concatenation is performed? If any of the two operands of a + operation is a string, string concatenation is performed. 'Looping ' is a string, hence 'Looping ' + i results in a string.
To change precedence or associativity, you have to use the grouping "operator" ((...)).

You mean console.log("Looping " + (i+1));
The "1" is being appended as a string.

console.log("Looping " + i+1); is being parsed from left to right, as ("Looping " + i) + 1. Add parentheses in the right spot and it should work:
console.log("Looping " + (i+1));

You are concatenating strings, not adding numbers. First, the value of i is cast to a string and concatenated to Looping, resulting in Looping 0. Then, the number 1 is cast to a string and concatenated as well, resulting in what you are seeing: Looping 01.
To get the result you want, you can simply put the i+1 in parentheses.
console.log("Looping " + (i+1));

the problem lies in the line where you do the actual logging :
console.log("Looping " + i+1);
First "Looping " + i happens.
Because "Looping" is a string, i gets cast to a string and appended to "Looping".
The result :
"Looping 0"
Then, the 1 gets added the same way.
"Looping 01"
If you want to keep this from happening, use parenthesis like so :
isNumeric: function(n){
for(var i = 0; i < n.length; i++){
console.log("Looping " + (i+1));
}
},

They are right to add the parentheses, the whole code would be:
isNumeric: function(n){
for(var i = 0; i < n.length; i++){
console.log("Looping " + (i+1));
}
},

Compare your results with this:
n=[1,2,3,4]
function isnum(n){
for(var i = 0; i < n.length; i++){
console.log("Looping " + i+1);
console.log("Looping " + (i+1));
}
}
isnum(n);
This generates the output:
Looping 01
Looping 1
Looping 11
Looping 2
Looping 21
Looping 3
Looping 31
Looping 4
In the statement "Looping " + i+1 what's happening is that "Looping " + i is happening first, i being cast to a string value for the concatenation with "Looping ". The 1 is also being cast as a string value for concatentation. By putting parens around the i+1 we can force (i+1) to happen first as addition before being concatenated, so the output is what you would expect.

Related

Compare two array and find match in Javascript

for(var i = 0; i < textList.length; i++){
for(var j = 0; j < titles.length; j++){
if(textList[i] === titles[j]){
console.log ("it includes my " + titles[j] + ' the match is ' +textList[i] + " counter " + i)
}
}
}
this is my code, but it won't return a match. I tried == and ===. But when i tested .includes() it worked. Can someone explain what's happening ?
If you are sure that all elements are in type String, you can use the method .search():
Prototype search
It will return the position of the match, if it dosent match in any position you will get -1 as return, soo > 0 it match.
I just tested your code with a very basic test example as follows:
let textList = ['book1', 'book2','book3']
let titles = ['book', ' tester', 'not_this', 'book2']
for(var i=0; i<textList.length;i++){
for(var j=0; j<titles.length;j++){
if (textList[i] === titles[j]){
console.log ("it includes my " + titles[j] + ' the match is ' +textList[i] + " counter " + i)
}
}
}
And I got the expected result it includes my book2 the match is book2 counter 1 so with this specific code I would suggest looking at you input arrays.
With regards to your question regarding why .includes() works and this doesn't, again we would need to se your input arrays but I would hazard a guess that it is something to do with the type checking within this function.
Finally, as others have suggested, there are other (more succinct) ways of achieving this with built in array functions, however your original question was about why this code in particular doesn't work so I've left these out.

NaN Issue - Why does identical code returns diffrent results?

I'm working on a script to match scrambled words to their unscrambled counterpart, and I'm running into a weird NaN problem. I have inserted comments below to guide you further in understand my problem in hopes that you can give me an explanation as to why this problem is occurring. Thank you for your time and help.
NOTE: Two chunks of code that are exactly the same (but with different variable names) act differently. The latter works, but the former does not.
<!DOCTYPE html>
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
</head>
<body>
<form id="words">
<input type="hidden" value="html:),121212,21122112,asdfjkl;,hal9000,1234qwer,1q2w3e,test123,gambit,sports,hello!,willie,hashtags,oneway,whoknows,whyowhy,youwho,theone,sweet!,wo0Oot">
</form>
<br>
<li>leho!l</li>
<li>lilwie</li>
<li>thahsags</li>
<li>yaneow</li>
<li>kwosonhw</li>
<li>ohhywwy</li>
<li>oyuwoh</li>
<li>otheen</li>
<li>e!stwe</li>
<li>wtoO0o</li>
<script>
var words, scram, wordVals, scramVals, sum, i, I;
// Turn word list into an array.
words = [];
var words = document.getElementById("words").elements[0].value.split(",");
// Turn scrambled word list into an array.
scram = [];
for (var i = 0; i < 10; i++) {
scram.push(document.getElementsByTagName("li")[i].innerHTML);
};
// Next I iterate through each letter of each word (for the unscrambled words)
// and convert those letters into ASCII values - adding those together
// to get the total ASCII value of each word.
wordVals = [];
for (i = 0; i < words.length; i++) {
for (I = 0; I < words[i].length; I++) {
sum += words[i].charCodeAt(I);
// console.log(sum)
// Using console.log(sum), you see that the first 6 iterations return NaN.
// Each iteration (ASCII Value) for the first word in this loop
// words[0].charCodeAt(0, 1, 2, 3, 4, 5, 6), all returned NaN.
// But each word after the first iteration calculates the ASCII values
// like it's supposed to.
};
wordVals.push(parseInt(sum));
sum = 0;
console.log("Word[" + i + "]: " + words[i] + " - Value: " + wordVals[i]);
};
// typeof WordVals[0] = number
console.log("typeof wordVals[0]?: " + typeof(wordVals[0]));
// isInteger = false
console.log("isInteger wordVals[0]?: " + Number.isInteger(wordVals[0]));
// Here I am iterating through each letter of each word (for the scrambled words)
// and converting those letters into ASCII values - adding those values together
// to get the total ASCII value of each word.
// **This loop uses the same exact code as the one above (but with different variables)
// and it works correctly. Why is this?
scramVals = [];
for (i = 0; i < scram.length; i++) {
for (I = 0; I < scram[i].length; I++) {
sum += scram[i].charCodeAt(I);
};
scramVals.push(sum);
sum = 0;
console.log("Scram Word[" + i + "]: " + scram[i] + " - Value: " + scramVals[i]);
};
</script>
</body>
</html>
OUTPUT:
Word[0]: html:) - Value: NaN
Word[1]: 121212 - Value: 297
...rest of list omitted...
typeof wordVals[0]?: number
isInteger wordVals[0]?: false
Scram Word[0]: leho!l - Value: 565
Scram Word[1]: lilwie - Value: 646
...rest of list omitted...
I have tried using a different starting word in my word list but get the same NaN result.
I don't understand why the first block of code doesn't work when it is practically identical to the second block of code that does work!
Why am I getting a NaN on the ASCII values of each letter of the first word?
I'm a beginner, and realize that this is not the proper way to go about finding word matches. Regular Expressions is probably what I will try to end up using, but I need to figure this out so I can progress in the way that I learn.
Thank you. I use this site all the time because I love the no nonsense approach most of you take in addressing user requests. There are a lot of really smart people here donating their time and intelligence, and I really appreciate it.
I am also open to any tips you can give me to improve this code.
That is because undefined + Number is NaN. Initially, the sum variable is undefined. that is why the first value in the wordVals array is NaN.
Just set sum to 0 and it should work as expected, ex:
var words, scram, wordVals, scramVals, sum = 0, i, I;
For the first iteration you adding a number with undefined( ie sum). So it'l become NaN. make sum = 0; at the beginning

jquery put comma between every variable except last

I have a script that will insert the checked checboxes and radios in the value() of an input tag.
var burgernavn = meat + " with " + bread + " and " + onion + tomato + cheese + salad;
$('#burger-navn').val(burgernavn);
Onion, tomato, cheese and salad needs to have1 " ," between them, except the last two who need " and " between them.
Thats the first thing.
Second thing is that these variables represent checkboxes, so they can be undefined, in which case they should not be put into $('#burger-navn').val(). They can all be undefined, in which case no commas or "and" should be put in.
I hope this is accomplishable.
Capture all checked values in an array (this makes sure that whatever values in this array, all are defined). Also, it will give you count of values that you need to pass to input box.
var checkedValues = document.getElementsByClassName('checkbox');
Iterate over this array, check for last values. (Check my comments in below code snippet)
var commaValues = "", otherValues= "";
//we are iterating only until (total values -2)
for(var i = 0; i < checkedValues.length - 2 ; i++){
//append comma with each value
commaValues += checkedValues[i].concat(",");
}
//append 'And' for last two values if total valuesa re more than one
if(checkedValues.length > 1){
otherValues = checkedValues[checkedValues.length-1].concat("and", checkedValues[checkedValues.length])
}
else if(checkedValues.length == 1){
otherValues = checkedValues[0];
}
//finally concat both strings and put this concated string in input
$('#burger-navn').val(otherValues.concat(commaValues));
So, I hope you got the idea. This code snippet might need a bit tweak since I didn't had your html code and sample data, but it is easily doable using this snippet as reference. Cheers
You can do this pretty easy with jQuery $.map.
var checkboxes = $('input:checkbox');
var commaString = $.map($('input:checkbox'), function( ele, i ) {
return $(ele).val() + (i + 2 == checkboxes.length ? " and" : (i + 1 != checkboxes.length) ? ",": "");
}).join(" ");

Getting NaN Error and undefined Error

I have a Problem with my push function in JavaScript.
<script type="text/javascript">
var myArr = []
var len = myArr.length
$.getJSON('daten.json', function(data) {
$.each(data,function(key,value) {
for(var i = 0; i <= len; i++){
myArr.push("<p>" + value.Name+i ," ", value.Nachname+i + "</p>")
}
})
$('.content').html(myArr.join(''))
})
</script>
I need to convert value.Name+i like this = value.Name0, value.Name1 and so on. I got a JSON File and the Keys are Dynamic, so the first entry got Name0 the second Name1 and so on. Now I must print the JSON file on my html page, but how I can write this line:
myArr.push("<p>" + value.Name+i ," ", value.Nachname+i + "</p>")
with my var i which increment in the loop, to call the Keys in my JSON file?
Like value.Name0. Doing value.Name+i and value.Name.i does not work.
It seems to me what you're looking for is something like this:
myArr.push("<p>" + value['Name'+i] ," ", value['Nachname'+i] + "</p>")
This portion of javascript is covered pretty nicely here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects
Take the object property in a variable, use condition to check if it has value or not then concat it
var nameval = value.name;
then use in your javascript variable
nameval+i
You need to convert your i (integer value) to string prior to adding it.
use:
value.Name + i.toString()
here's the jfiddle link: http://jsfiddle.net/kpqmp49o/

Javascript unexpected assignment behavior

I'm writing a function to replace all occurrences of variables p and q with their respective values without using eval(), however, I'm running into some unexpected behaviors. BTW, I'm using phpjs for the str_replace
Fiddle: http://jsfiddle.net/5Uedt/2/
function table(str){
str=str_replace(["nand","nor","implies","equals","not","xor","and","or","(",")"],[" 3 "," 4 "," 5 "," 6 "," 7 "," 8 ", " 9 ", " 10 ", " ( "," ) "],str).replace(/\s{2,}/g, ' ').trim();
str=str_replace(["3","4","5","6","7","8", "9", "10", "(",")"],["nand","nor","implies","equals","not","xor","and","or","(",")"],str).split(" ");
var vars={p:1,q:1};
for(vars['p']=1;vars['p']>=0;vars['p']--){
for(vars['q']=1;vars['q']>=0;vars['q']--){
alert(str);
newinput=str;
for(var i=0;i<newinput.length;i++){
var token=newinput[i];
if(token.length===1){
console.log(newinput[i]);
newinput[i]=vars[newinput[i]];
}
}
// console.log(n.join(" "));
}
}
}
I have this code for replacing all occurrences, but it's not working. I'm alerting the original string entered in every time, however, the string changes. The expected output of the function is p,and,q repeated 4 times, instead, I have p,and,q, then 1,and,1 repeated 3 times. However, I don't seem to have any assignments to str. Does anyone know why this is happening?
When you set newinput equal to str, you're still referencing that original object. When you change the value later in newinput you affect the str variable.
If you want to clone the object you can iterate over the properties of str like so:
var newinput = {};
for(var key in str) {
newinput[key] = str[key];
}
Thus making a clone of your original object and you won't be affecting it's values. Assuming you don't have objects you want to clone inside your str object. If you do, just run this function recursively.
Updated Fiddle

Categories

Resources