Problems with nested loops in Javascript - javascript

I'm trying to do a nested loop in javascript, it's my first time doing this kind of things and i have a lot of doubts :(!
I need to get the times a variable is printed or used into a loop, and the first thing that passed through my mind was using .length... And I thought it worked... But it did not, or I don't know if it did.
When i used the length method, i get this in the console: Console Message
That's the value that i need, but i don't know if I can work with it, i don't even know the value's name and it appears like "undefined" :(!
And i just can't use a console.log on the variable out of the loop because it returns just the last value on it, and not specifically the number of times this is printed on.
If you have more doubts, take a look of my code, maybe it can clarify you guys.
function calculatingDays(day, month, year, current_day, current_month, current_year, final_day, callback){
for (k = year; k <= (year + 1); k++){
for (i = current_month; i <= 12; i++){
for (j = current_day; j <= final_day; j++) {
console.log(j.length)
if (j === day && i === month) {break}
}
final_day = new Date(year, i, 0);
final_day = final_day.getDate();
current_day = 1;
if (j === day && i === month) {break}
}
if (j === day && i === month) {break}
}
}
}

What you need is something that can hold the count of times something has occurred. This can best be done by a variable that you can increment. What does this look like?
var counter = 0;
// later on when you find you need to increment the counter
counter = counter + 1;
Then after you're done looping you can do console.log(counter). In your code you want the var counter = 0 to occur right above the first for loop. Where you are currently doing console.log(j.length) is where you increment the counter. Then choose a spot outside of the loop that you want to print it. You have several loops and I'm not sure when you want to print the counter.

Related

Print even number using for loop without using if condition

I have an easy drill to print all the even numbers between 1-1000.
I want to set the condition in the line of the loop and not below it..
This is what I've tried:
for (let i = 1; i <= 1000 && i % 2 == 0 ; i++) {
document.write(i + " ");
// I dont want the condition here !!!
}
I searched the forum and tried this too:
for (let i = 1;( (i <= 1000) && (i % 2 == 0) ); i++) {
document.write(i + " ");
}
It looks like the same code I think, but there is nothing in the console when I run the code..
The test condition in the loop header determines whether the loop will continue to iterate. Because the first value of i is 1, and 1 is not even, the loop body is never run.
The whole test expression must be true (well, "truthy") for the loop not to stop. Therefore, you cannot place the evenness test in the loop header. It must be a separate test inside the loop body.
Now, you could do this without a test by starting the iteration at 2 instead of 1 and adding 2 on each iteration. Then you don't need to test for evenness at all:
for (let i = 2; i <= 1000; i += 2)
document.write(i);

Break and Continues

I wonder if someone can clarify something for me. I have a bit of code to check an array for overlapping values depending on different values. Basically its the contents of a google sheet in rows and comumns for this is specifically GAS. What I have at the moment is
var e = [[2,4,3,4,2],[1,5,3,6,2],[2,4,3,4,1],[1,4,3,6,1],[2,4,3,6,5]];
var i; //id of entry to check
var j; //id of element to check
var k; //id of entry to compare
for (i in e){ //2D ARRAY ARRAY
for (k in e){ //ELEMENT TO COMPARE
if (e[i][2] === e[k][2] && e[i][3] === e[k][3] && e[i][0] && e[i][0] >= e[k][0] && e[i][1] <= e[k][1] && e[i][4] <= e[k][4] && i !=k){
e.splice(i,1);
continue;
}
}
}
return e;
I had to add the continue; as otherwise if the last array checked was also marked for splice the code failed. But I assumed break would also work in place of continue but for some reason it does not. I thought break would return to the outside loop but does it permanently break that bit of code?
Thanks people
EDIT: spoke too soon. code still fails even with continue. head scratching continues
continue jumps directly to the next iteration, so:
while(true) {
console.log("a");
continue;
console.log("b");
}
will only log a as it will jump back to the beginnig of the loop if it reaches continue.If you however move continue to the last line of the loop (just as in your code) it does nothing as it would jump to the begining to the loop one line later, so it just skips an empty line.
I thought break would return to the outside loop
Yup, thats what happens and that is actually a good thing as if you removed the element already, it won't make sense to check for other dupes as you don't want to remove it twice.
Now the real problem is that splice changes the indexes, so if you splice out the fourth element, the fith element becomes the fourth element, but the loop continues to the fith element without checking the fourth element again (which is now a different one). Therefore you have to go back by one element before you break:
for(let i = 0; i < e.length; i++) {
for(let k = 0; k < e.length; k++) {
if(i === k) continue; // < good usecase
if(/* equality checks */) {
e.splice(i, 1); // remove the element
i--; // go back by one as we changed the order
break; // exit the inner loop
}
}
}
IMO:
1) I would favor for(const [i, value] of arr.entries() over for..in
2) you will forget what arr[i][2] is very soon, giving proper names to the indexes makes it way more readable:
const [idA, someValueA] = e[i];
const [idB, someValueB] = e[k];
if(idA === idB && someValueA <= someValueB // ...
3) e is a bad name.
You can use a labelled break to break out of nested loops.
eg
var num = 0;
outermost:
for(var i = 0; i < 10; i++){
for(var j = 0; j < 10 ; j++){
if(i == 5 && j == 5){
break outermost;
}
num++;
}
}

For loop homework

I have homework and these are my instructions:
create javascript 06.js with a general function: addThemUp()
There is NO HTML page. There is NO EVENT HANDLER.
The function receives two parameters. They go between (..).
Use any names you want for the parameters but you could use descriptive names
Add all integers from the first parameter to the second.
All you need to do is use a for() loop and return the total.
Return the total of the integers. Use return because this is a general function.
Here is my code
function addThemUp(earlier,later) {
var total = 0;
for (i = 0; i <= earlier; i ++) {
total = total + 0;
};
return total;
};
For some reason this one is messing up bad. We were able to do this exact same thing with Count but adding up and array seems to be different. When I run it through the grader I'm only receiving 25% grade.
You need to make use of both earlier and later in your loop:
function addThemUp(earlier,later) {
var total = 0;
for (i = earlier; i <= later; i ++) {
total = total + i;
};
return total;
};
Shouldn't it be using
i <= later
As it would stop on the first value otherwise?
I'll point out two things that could help you on your way.
First: this line
total = total + 0;
Think about what it's doing for a bit.
total (which starts as 0) is adding... 0... to itself. ;)
Next, this line:
for (i = 0; i <= earlier; i ++) {
IIRC, earlier is the first of the two numbers you're concerned about.
That part of the for loop says "stop when this condition is met." ;)

counter variable is holding 2 values on 2nd pass of the function

I'm making a typing game. When multiple players play the game it runs through the same set of functions again. I'm using the variable j as a counter to advance words when they are typed correctly. For some reason, on the second pass on each upkeystroke, it logs j = 1 & j = whatever the value of the previous players last word + 1 is. When each player plays, I want each set of words they are typing to be the same, so that it is fair. I can't figure out why this is happening or even how the variable has 2 values at the same time?!?!?
What gives?
Here's the code in question, but there's a bunch of callbacks that could be involved, although the only place this variable is called is inside this function.
//advances ship on correct typing
function runRace() {
timer();
var j = 1;
//BUG HERE !! Works fine on first iteration but on second
//iterations value jumps beteween 1 and whatever the next
//one is. It's like on every keystroke it reassigns var j
//back to 1, then back to the element number it was on
//last time
//!!! j has 2 values !!!it's keeping the value from the
//prior running of run race
$(document).keyup(function(e){
var targetWord = $(".toType").text();
var typedWord = $("#word").val();
//while (j < gameWords.length){
console.log("j = " + j);
if(typedWord === targetWord){
$(".player").css({left: "+=15px",});
targetWord = $(".toType").text(gameWords[j]);
$("#word").val("");
j++;
}else {
return
};
//}
});
}
If you need to see the rest of the code to figure this out, it's here. Eventhough it's not running right on jsfiddle for reason, it works other then the bug, locally https://jsfiddle.net/ujsr139r/1/
As i mentioned in my comment you're creating multiple listeners everytime runRace() is called.
You could try something like this instead (please note, this isn't the best way to do this, i'm just demoing. Global variables like j in this case aren't a clever idea.:
var j=1; // global because its outside of your function
$(function(){
$(document).keyup(function(e){
var targetWord = $(".toType").text();
var typedWord = $("#word").val();
//while (j < gameWords.length){
console.log("j = " + j);
if(typedWord === targetWord){
$(".player").css({left: "+=15px",});
targetWord = $(".toType").text(gameWords[j]);
$("#word").val("");
j++;
}else {
return
};
//}
});
});
//advances ship on correct typing
function runRace() {
j = 1;
timer();
}

For Loop Manipulate Multidimensional Array Javascript

Okay so I have a 2D array that I am trying to alter using javascript. This is what I have so far:
for (var i = 0; i <= inputData.length; i++ {
inputData[0,0] = inputData[0,0];
inputData[i,0] = inputData[((i - 1) + 1/12), 0];
I want this to take array [i-1] value and then add 1/12 to it
for (j = 13; inputData.length; j += 13) {
delete inputData[j,0];
delete inputData[j,1];
}
Also, I want to delete the entire 2D array at every 13th increment value.
}
This is what I have so far. I am sure there are probably errors within it. Can you guys help me out here? Any help would be greatly appreciated.
Couple of things - you need to be careful when iterating over an array that you're removing from, your indexes will end up offset with respect to your data as soon as you do a delete. Secondly your syntax for deletion is off.
Normally in these situations I favour creating a new array containing the data I want to keep.
var inputData = [[1,1],[2,2],[3,3],[4,4]];
var b = [];
for (i=0; i < inputData.length; i++) {
if ((i + 1) % 13 != 0) {
var year_with_month = inputData[i][0] + i * 1/12;
var e = [year_with_month, inputData[i][1]]
b.push(e);
}
}
inputData = b;
Also, given a choice I'd use a library like underscore to make it easy to do the looping. I never manually write for loops anymore, took me a couple of attempts to get that one right :)

Categories

Resources