Regarding Nested For Loops

For nest for loops, why does the initialization variable need to be different for each loop?
I know its wrong to have the same variable, but I don’t get why?

example:

Correct Way
const bobsFollowers = ["Andy", "Brock", "Charles", "David"];
const tinasFollowers = ["Andy", "Beck", "Charles"];

const mutualFollowers = [];

for(let i = 0; i < bobsFollowers.length; i++) { 
  for (let j = 0; j < tinasFollowers.length; j++) { 
    if(tinasFollowers[j] === bobsFollowers[i]){
      mutualFollowers.push(tinasFollowers[j]);
    }
  }
}

console.log(mutualFollowers); //["Andy", "Charles"]
Wrong Way
const bobsFollowers = ["Andy", "Brock", "Charles", "David"];
const tinasFollowers = ["Andy", "Beck", "Charles"];

const mutualFollowers = [];

for(let i = 0; i < bobsFollowers.length; i++) { 
  for (let i = 0; i < tinasFollowers.length; i++) { 
    if(tinasFollowers[i] === bobsFollowers[i]){
      mutualFollowers.push(tinasFollowers[i]);
    }
  }
}

console.log(mutualFollowers); //['Charles', 'Andy', 'Charles', 'Andy', 'Charles', 'Andy', 'Charles' ]

Thank you

If you had two completely separate loops, it would be fine to use the same variable, but since you are nesting the for loops, you want to be able to properly distinguish what variable you are working with. This will help you avoid weird and unexpected output (since doing it with the same variables will not give you an error).

For each outer loop, i represents a number in range of the length of the bobFollowers array.
For each inner loop, j represents a number in range of the length of the tinasFollowers array.

i and j represent TWO different things.

If you run this code, how do you know that the computer is going to know how to distinguish i, which represents bobsFollowers index numbers, from i, tinasFollowers index numbers (see how that sentence made 0 sense because how would you know if i is different than i)?
Which is why your output on the “Wrong Way” is weird and incorrect.

3 Likes

The two i's are different variables, but your ‘Wrong’ way isn’t comparing each element of bobsFollowers to each element of tinasFollowers. Since your comparison is made inside the nested for loop, you are only comparing each element of one array to the single element of the other array with the same index as represented by the inner i. You are performing that comparison, and then pushing the element of tinasFollowers, if it matches the corresponding element of bobsFollowers, to the mutualFollowersArray 4 times (4 is the length of bobsFollowers). If you changed the order of the names so that the indices of the matching names didn’t match, you’d get an empty array for your result:

const bobsFollowers = ["Andy", "Brock", "Charles", "David"];
const tinasFollowers = ["Beck", "Charles", "Andy"];

const mutualFollowers = [];

for(let i = 0; i < bobsFollowers.length; i++) { 
  for (let i = 0; i < tinasFollowers.length; i++) { 
    if(tinasFollowers[i] === bobsFollowers[i]){
      mutualFollowers.push(tinasFollowers[i]);
    }
  }
}

console.log(mutualFollowers); 

Output:

[]

Depending on what you’re doing, you can use the same iterator variable. This works for example, but is confusing to read:

//will repeat a count down from 3, 5 times
for(let i = 1; i <= 5; i++) {
  console.log("outer i:", i);
  for(let i = 3; i > 0; i--) {
    console.log("inner i:", i);
  }
}
Output:

outer i: 1
inner i: 3
inner i: 2
inner i: 1
outer i: 2
inner i: 3
inner i: 2
inner i: 1
outer i: 3
inner i: 3
inner i: 2
inner i: 1
outer i: 4
inner i: 3
inner i: 2
inner i: 1
outer i: 5
inner i: 3
inner i: 2
inner i: 1

The following code, however, would throw an error:

//Try to count down from the value of the outer iterator 5 times
for(let i = 1; i <= 5; i++) {
  console.log("outer i:", i);
  for(let i = i; i > 0; i--) { //set the inner iterator equal to the value of the outer iterator
    console.log("inner i:", i);
  }
}

Output:

outer i: 1
ReferenceError: i is not defined

The error refers to:

for(let i = i; ...) //since i was just declared with this let, it has no value, and the second i is the same undefined variable just declared

Changing one of the iterators would accomplish the task:

for(let i = 1; i <= 5; i++) {
  console.log("outer i:", i);
  for(let j = i; j > 0; j--) { //set the inner iterator equal to the value of the outer iterator
    console.log("inner j:", j);
  }
}
Output:

outer i: 1
inner j: 1
outer i: 2
inner j: 2
inner j: 1
outer i: 3
inner j: 3
inner j: 2
inner j: 1
outer i: 4
inner j: 4
inner j: 3
inner j: 2
inner j: 1
outer i: 5
inner j: 5
inner j: 4
inner j: 3
inner j: 2
inner j: 1

To sum up, using the same iterator may work depending on what you’re doing, but is always a bad practice since it makes your code confusing to read.

2 Likes