Return Largest Numbers in Arrays -- Why is my answer no good?

I’ve read through other solutions, check StackOverflow, and have looked at the hint, but my brain is hurting trying to understand why my solution doesn’t work and why the other solutions do.

Essentially I have 2 loops right after each other, but I’ve separated them out so that I can check as I go that I’m getting the values I want. I’m doing this with console.logs and also with assignments.

The console messages seem kind of right, but I don’t get the right solution.

What I’ve noticed is people using multi-dimensional arrays, like arr[i][n]. But I think I already have this by assigning arr[i] to eachArr, and then using eachArr[n]. Why does this not work?

function largestOfFour(arr) {

  let eachArr = 0;
  let val = 0;
  // set 2 values to 0
  let newArr = [];

  //go through an array
  for (let i = 0; i < arr.length; i++) {
    console.log("This arr: " + i);
    // console.log(arr.length);

    //get all the values for each sub array
    eachArr = arr[i];
    console.log("Items for arr " + i + " is " + eachArr);
    // console.log("the array position is: " + pos); 
    for (let n = 0; n < 5; n++) {
      console.log(eachArr[n]);
      if (val < eachArr[n]) {
        //if val is less than each arr value

        val = eachArr[n];
        //set value to value of arr

        console.log("New Value is " + val);
        newArr.push(val);

      }
    }
  }

  return newArr;

  // console.log(newArr);
  // return arr; 
}

largestOfFour([
  [4, 5, 1, 3],
  [13, 27, 18, 26],
  [32, 35, 37, 39],
  [1000, 1001, 857, 1]
]);

UPDATE: I’m considering this solved on my end. I tried going through the solution, to figure out where I went wrong. And I haven’t been able to run the FCC basic solution through JS Bin without error. When I add some of the changes from the FCC solution to my code, it generates other errors. So, I’m moving on, or maybe I’ll ask on StackOverflow. Thanks if you tried to help.

I added a console.log(newArr) to the bottom right before the return statements and it showed that newArr is currently [4, 5, 13, 27].

This is happening because newArr.push(val); is happening inside of the if statement. So every time the current item in the subarray is greater than val, it gets pushed to newArr. That’s why both 4 and 5 are being pushed from the first subarray, but then not 1 or 3 because they are less than val (which at this point equals 5).

Then in the second subarray, 13 and 27 are both pushed to newArr because they are also larger than val… but not 18 or 26, because they are smaller (by this time, val equals 27).

If you really prefer using eachArr[n] to arr[i][n] notation, I think you can still make it work. But you need to change the logic of when a value should be pushed to newArr. (It should happen once per subarray, as part of your first for loop.)

The function never gets to the 2nd or 3rd subarrays because of the way the second for loop is set up (n < 5). If you set it to n < eachArr.length, it will keep going for as long as it should. :slight_smile:

Thanks. I made a few small changes based on your suggestions.

Initially it was only returning an array of 3. I changed n = 0 to n = 1. I’m not sure why this helps, but doing so gives me the array of 3 instead of an array of 2.

Can you explain why n < eachArr.length works better than n < 5? eachArr[n] seemed to give me the right answer, but it’s not passing yet.

I took out the first loop since the issue seems to be with the second loop.

    for (let n = 1; n < eachArr[n]; n++) {
      if (val < eachArr[n]) {
        console.log("Check this " + val + " value against " + eachArr[n]);
        //if val is less than each arr value
        val = eachArr[n];
        //set value to value of arr
        console.log("New Value is " + val);
      }  
    }  
    newArr.push(val); 
    console.log(newArr);
  }
 return newArr; 
  // return arr; 
} 

Did you mean to say n < eachArr.length here?

If you start with n = 1, it will begin on the second item in each array. This works ok for the tests here because the first number in each subarray is never the largest. :sweat_smile: But that’s pure luck! It is better practice to always initialize with i = 0 so that every item in the array will be checked.

Similarly, it is a better habit to say n < eachArr.length because that way your loop will continue to the end of the array. In this case, every subarray has a length of 4, but that is very specific to this challenge.

At this point, I would recommend looking at “Get a Hint” and reading over the “Basic Code Solution”, which uses nested for loops. Try comparing its logic to your code and see if you can find where yours is going astray. :+1:

I used n = 1 because I wasn’t getting through more than 2 arrays with n=0.

I switched to checking in JSBin, instead of just relying on the console and FCC console. In JSBin I get the same results with n < eachArr.length as with n < eachArr[n]. When I wasn’t using JSBin, I wasn’t getting good results with eachArr.length, so that’s why I used n < eachArr[n]. It was only getting through 3 arrays, not 4.

Anyway, I get [5, 27, 39, 1001], with either option but neither passes the quiz.

consider that some of the arrays have negative numbers, so if your subarray is [-3, -9, -1001, -4] when you do let n = 1; n < eachArr[n]; n++ it will never execute because n which starts at 1 will never be smaller than the negative numbers - that is a reason for which you should use let n = 0; n < eachArr.length; n++

After that you have an other issue - if you set val = eachArr[n] but you don’t reset the value of val some arrays will never have a number that is higher of previous ones (like the array with negative numbers) so a number from that array will never be selected

let n = 1; n < eachArr[n]; n++ or let n = 1; n < eachArr.length; n++

The only thing these loops do is to go through each sub-array position; they do not compare the value of the array position to 0 or 1. So at this point, whether or not the value is positive or negative makes no difference. It’s going to the array position 0-3. If you add console.log(n); immediately after the for loop, you’ll get 0-3 as values. But, yes, eachArr.length is the better way to go through the loop.

The if-statement is where the comparison to the value of the array position takes place. if (val < eachArr[n]).

I’m not exactly sure where to reset val, but I think it has something to do with the if/else.

If you use the loop with n < eachArr[n] with the array I posted before you get this:

  • the loop start, n is initialised at 1
  • the condition is checked, eachArr[n] is -9, 1 < -9 is false. Loop stops

If you use let n = 0; n < eachArr.length; n++

  • loop starts: n is initialised at 0
  • condition is checked: eachArr.length is 4, 0 < 4 is true so the loop body is executed
    Etc

I don’t know if you saw my update but I decided to move on from this question. I wasn’t able to get the official “hint” answer to run without errors in JS Bin, so I’m moving on. Using that solution, didn’t result as expected in different test environments.

It’s not really possible to articulate in writing all the changes that ended up getting testing at the speed they got tested. I moved on from using eachArr[n] a long time ago, although I appreciate the help. At one time, it worked. I just want to move on.

Do you have a link to the JS Bin code you tried?

I closed all the browser windows I had open so I’m not able to replicate exactly what I entered to get my unexpected results. It’s possible I didn’t copy/paste exactly. But I think the error I got was something like, illegal return.