Why is this variable declaration necessary?

spoilers for JS intermediate problem “Drop it”

|
|
|
|
|
|

Hi! Completing the JS Intermediate problems, and came across “Drop it”. It sounded easy enough, and I drew up this:

function dropElements(arr, func) {
  for (let i = 0; i < arr.length; i++) {
    if (func(arr[0])) {
      break;
    } else {
      arr.shift();
    }
  }
  return arr;
}

I threw one error, the case of returning and empty array. After lots of hair pulling over a seemingly easy problem, I checked the hints and saw that the solution had one extra line - a variable declaration for arr.length before the loop. Just switching that one line made the test pass. Why?? What happens in a variable declaration here that doesn’t happen inline?

Thanks!
Caymus

Hi @breadboy17. Welcome to FCC.
The clue is in your failing test. Essentially as you loop through the elements of the array, you are removing the first element if the function passed as second argument returns false when invoked with the first element in the array. You are increasing i and at the same time reducing the length of the array as you remove elements from it. You will reach a point where you will exit the loop without iterating through all the elements if the condition you are checking doesn’t evaluate to true. For example look at the test below

dropElements([1, 2, 3, 4], function(n) {return n > 5;}) should return []

Using your function above let us see what is happening.

  1. If i = 0 , i < arr.length evaluates to true. You execute the body of the for loop. func(arr[0]) evaluates to false because the function passed as argument returns true if the value passed is greater than 5. You remove first element reducing the length of the array by 1 and i becomes 1 from i++.
  2. i < arr.length evaluates to true once again. Take note the length of array has reduced by 1. The length is now 3. You enter the body of the for loop again removing the first element. The length of the array reduces to 2 and you increase i to 2.
  3. i < arr.length evaluates to false because 2 < 2 is false. You exit the for loop without evaluating two elements. Instead of returning [], you return [ 3, 4 ].

The purpose of declaring arr.length outside the loop is to keep its value fixed so that all the elements in the array are evaluated in case none of them evaluates to true inside the loop. If you want to traverse all of them with your solution, then reduce i by 1 after removing the first element inside the else clause like

   arr.shift();
   i--;

The difference between your solution above and the one given in the hint is you are dynamically calculating the length of the array in each iteration but the hint has fixed the array length so as to traverse all the element in case a situation like described arises.

2 Likes