JavaScript - Simple If inside For - javascript

Having an issue with the following as I learn JS basics. My If was working before I stuck it inside the For, but now nothing seems to be working. Thought about doing forEach but seems like a complex solution for such a simple problem (creating another function to run forEach with). Also been running it through online code checkers and it is coming back clean.
Hoping I'm doing something ignorant like misaligned tabs..
"use strict";
function scan(inputArray) {
var count = 0,
iter = 0,
len = inputArray.length;
for (iter = 0; iter < len; iter + 1) {
console.log("inside for: " + iter); //diagnostic line, does not display
if (inputArray[iter] === "contraband") {
console.log("inside if: " + iter); //diagnostic line, does not display
count += 1;
} //end if
} //end for
return count;
} //end function -scan-
// Test Code
const numItems = scan(['contraband', 'dog', 'contraband', 'cat', 'zippers', 'contraband']);
console.log('Number of "contraband": ' + numItems); // should be 3

In a for loop you need to have 3 statements, which are:
Statement 1 -- is executed (one time) before the execution of the code block;
Statement 2 -- defines the condition for executing the code block;
Statement 3 -- is executed (every time) after the code block has been executed.
The reason why your code is not working is that you had a mistake in the 3rd statement, where you wrote iter + 1, without really changing the value of iter. What you had to do is write in the 3rd statement iter = iter + 1 OR iter += 1 OR iter++, and all of these change the value of iter to +1.
The for loop should be like this:
for(iter = 0; iter < len; iter++) {
...
}

Please try below code.
the iter variable should be less than length of the array
The iter should be incremented to make the access to elemenst of the array.
"use strict";
function scan(inputArray) {
var count = 0,
iter = 0,
len = inputArray.length;
for (iter = 0; iter < len; iter++) {
console.log("inside for: " + iter); //diagnostic line, does not display
if (inputArray[iter] === "contraband") {
console.log("inside if: " + iter); //diagnostic line, does not display
count += 1;
} //end if
} //end for
return count;
} //end function -scan-
// Test Code
const numItems = scan(['contraband', 'dog', 'contraband', 'cat', 'zippers', 'contraband']);
console.log('Number of "contraband": ' + numItems); // should be 3

Related

Removing alert from code forces it to enter infinite loop

I have a piece of code that has a few window alert messages. It works fine. However, if I remove the alert statements, the program enters into an infinite loop. This is weird for me.
Can someone help me identify the problem with the code?
function countSwaps(arr) {
let notVisited = {}, swaps = 0;
for (let i = 0; i < arr.length; i++) {
notVisited[i] = true;
}
while (Object.keys(notVisited).length) {
alert("main pass");
let nextPos, currentPos = Object.keys(notVisited)[0];
while (arr[currentPos] !== parseInt(currentPos+1)) {
nextPos = arr[currentPos] - 1;
[arr[currentPos], arr[nextPos]] = [arr[nextPos], arr[currentPos]];
swaps+= 1;
alert("Swap " + arr[currentPos] + " and " + arr[nextPos] + "\n");
delete notVisited[nextPos];
}
delete notVisited[currentPos];
}
return swaps;
}
console.log(countSwaps([2,3,4,1,5]));
Well, it runs an infinite loop for me without the alerts as well.
It seems like the problem is the following expression: parseInt(currentPos+1)
The addition happens before the conversion from a string to a number, so for example:
currentPos = '4';
currentPos + 1 == '41';
parseInt(currentPos + 1) == 41
What you want is probably parseInt(currentPos) + 1. Now:
currentPos = '4';
parseInt(currentPos) + 1 == 5
With this the loop seems to quit and I get the result of 3 swaps out of it.
This is cause of infinite loop.
while (Object.keys(notVisited).length)
It should be something like
while (Object.keys(notVisited).length > 0)
That is a property, it will always return true

Variables not what I expect in a loop

I've looked at this questions, but I'm still stuck at this JavaScript closure inside loops – simple practical example
Here's my code
template[prop['Name']] = [];
var processedCounter = -1;
$.each(prop.Properties, function (key, value) {
console.log(processedCounter + 'outside');
$.getJSON(value['Url']).done(function (jsres) {
console.log(processedCounter + 'inside');
var numItems = jsres[itemCount].length;
if (template[prop['Name']].length == 0) {
console.log('this should only be printed once');
for (var i = 0; i < numItems; i++) {
template[prop['Name']].push({});
}
}
processedCounter += 1;
});
});
There's several issues. First it that it prints the message 'this should only be printed once' two times. Second is that the value of processedCounter has to be -1 instead of 0, because the value is increased at the wrong time.

Getting 'undefined', can't figure out why

Working my way through 'Eloquent Javascript' and I'm hitting a bit of a roadblock in understanding how to properly use if with for statements in the language. I'm supposed to write a function that counts all instances of the uppercase 'B' in a given string. The code I've written thus far:
function countBs(s) {
var counter = 0;
for (i = 0; i < s.length; i++) {
if ('B' == s.charAt(i)) {}
counter += 1;
}
}
console.log(countBs("BBC"));
expected output: 2
actual output: undefined
Is my loop going wrong, or my 'if'?
You have two bugs
You are incrementing your counter outside of the if statement.
You have no return statement.
The following can be used:
function countBs(s){
var counter = 0;
for(i = 0; i < s.length; i++){
if ('B' == s.charAt(i)) {
counter += 1; // this needs to be inside the if statement
}
}
return counter;
}
Your function does not have a return statement.
A few issues.
function countBs(s) {
var counter = 0;
for (i = 0; i < s.length; i++) {
if ('B' == s.charAt(i)) {
++counter;
}
}
return counter;
}
document.write(countBs("BBC"));
You were not returning counter at the end of the function
Your if statement was opened, then immediately closed, so nothing happens if the character was B
Even if you returned counter and fixed the above 2 errors, the function still would have exited after 1 B was found. To fix this, move the return after the for ends.
If you're interested, the same problem can be solved with this one-liner:
function countBs(s) {
return s.match(/B/g).length;
}
document.write(countBs("BBC"));
Which finds all B characters (case-sensitive), puts them into an array, then returns how many items are in that array.

For loop in Javascript runs only once

Here is my code. I do not quite understand why the for loop runs only once, both inner and outer. nodeList.length and innerNodeList.length show appropriate values when I generate alert messages. I see that both i and j do not increment beyond 0. Kindly point out anything wrong with the code.
function getCategoryElements() {
var newCategoryDiv = document.getElementById("category");
var nodeList = newCategoryDiv.childNodes;
for (var i = 0; i < nodeList.length; ++i) {
var innerNodeList = nodeList[i].childNodes;
alert("innerNodeList Length" + innerNodeList.length.toString());
for (var j = 0; j < innerNodeList.length; ++j) {
if (innerNodeList[j].nodeName == "SELECT") {
alert("inside select Node value " + innerNodeList[j].nodeValue.toString());
document.getElementById("newCategories").value =
document.getElementById("newCategories").value + '<%=delimiter%>' + innerNodeList[j].nodeValue;
} else if (innerNodeList[j].nodeName == "TEXTAREA") {
document.getElementById("newCategoriesData").value =
document.getElementById("newCategoriesData").value + '<%=delimiter%>' + innerNodeList[j].nodeValue;
}
}
}
}
var newCategoryDiv, nodeList, innerNodeList, innerNode, i, j;
newCategoryDiv = document.getElementById("category");
nodeList = newCategoryDiv.childNodes;
for (i = 0; i < nodeList.length; ++i) {
innerNodeList = nodeList[i].childNodes;
alert("innerNodeList Length" + innerNodeList.length.toString());
for (j = 0; j < innerNodeList.length; ++j) {
innerNode = innerNodeList[j];
if (innerNode.nodeName === "SELECT") {
alert("inside select Node value " + innerNode.nodeValue.toString());
document.getElementById("newCategories").value += '<%=delimiter%>' + innerNode.nodeValue;
} else if (innerNode.nodeName === "TEXTAREA") {
document.getElementById("newCategoriesData").value += '<%=delimiter%>' + innerNode.nodeValue;
}
// Will this work?
alert('Does this alert appear');
}
}
I took the liberty to refactor your code and clean it up a little bit. In case you're not aware, all variables have function scope in Javascript, so no matter where you declare them within a single function, Javascript treats them as if the variable declaration is the first statement.
It appears that your code is syntactically correct, and so I think that the most logical place to look for a problem is that there could be an error occurring after the last alert function call.
In order to check this, try adding another alert function call to the end of the inner loop. If it doesn't run, you'll know this is the case.

Recursion, Sigma Notation (html/javascript)

my objective is to use recursion to get sigma notation working. top limit is n(input variable) bottom limit is i=1, and the function is (-i)^(i-1). i got it working with iteration but i cant get the recursion to work.
<!DOCTYPE html>
<head><title>Recursion</title></head>
<body>
<h1>Recursion</h1>
<script = "text/javascript">
var num
var i;
var n;
var total;
total = 0;
i=0;
var b;
b=0;
function formula(n)
{
(Math.pow((-i),(i-1)))
}
function recursion(n)
{
i=i+1;
if ((n-i) == 0)
{
document.writeln("done");
}
else
{
total = total + recursion(formula(n-i));
return total;
//total = total + (Math.pow((-i),(i-1)) + recursion(n-i));
}
}
num = window.prompt("pick a number");
recursion(num);
document.writeln(recursion(num));
//document.writeln(total);
</script>
</body>
</html>
Please avoid any global variables, that makes it very hard to read. Also, indent your code properly; and don't mix the output (document.write) into the computation. If you don't understand the recursion, just use a loop:
var total = 0;
for (var i=1; i<=n; i++)
total += formula(i);
return total; // the result
The same thing, done with recursion:
function sumFormulaUpTo (n) {
if (n <= 0) // the abort condition
return 0;
else
return sumFormulaUpTo(n-1) + formula(n);
}
sumFormulaUpTo(100);
You notice: there is no total variable, only the result of the recursively called function is used.
With an end recursion (more like the loop), it would look like this:
function sumFormulaFromTo(total, i, n) {
if ( i > n )
return total;
else {
var newtotal = total + formula(i);
return sumFormulaFromTo(newtotal, i+1, n);
}
}
sumFormulaFromTo(0, 1, 100);
If you had total and n declared statically outside the function, it would look more like yours. Yet, you forgot to return the result once the end condition is met (you just output something, but return undefined), and you somehow called the recursion with the result of formula - no idea where you got that from. This causes an infinite loop, according to #cbayram.

Categories

Resources