Chunky Monkey_Tips on how to set number of group divisions


#1

I think I’m taking the wrong approach. Wondering if I could get some tips (without solutions). Thank you in advance.

I’m certain there’s an easier way to divide the array into the correct number of groups (subarrays). The following solution satisfies the first three conditions on https://www.freecodecamp.org/challenges/chunky-monkey:
chunkArrayInGroups([“a”, “b”, “c”, “d”], 2) should return [[“a”, “b”], [“c”, “d”]].
chunkArrayInGroups([0, 1, 2, 3, 4, 5], 3) should return [[0, 1, 2], [3, 4, 5]].
chunkArrayInGroups([0, 1, 2, 3, 4, 5], 2) should return [[0, 1], [2, 3], [4, 5]].

function chunkArrayInGroups(arr, size) {
  var newArray = [];
  for (var i = 0; i < Math.floor(arr.length/size); i++) {
    newArray[i] = arr.slice(size*i,size*(i+1));
  }
  return newArray;
}
chunkArrayInGroups();

It doesn’t satisfy the other four conditions:
chunkArrayInGroups([0, 1, 2, 3, 4, 5], 4) should return [[0, 1, 2, 3], [4, 5]].
chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6], 3) should return [[0, 1, 2], [3, 4, 5], [6]].
chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6, 7, 8], 4) should return [[0, 1, 2, 3], [4, 5, 6, 7], [8]].
chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6, 7, 8], 2) should return [[0, 1], [2, 3], [4, 5], [6, 7], [8]].

In order to do so, I need to change the second parameter in the for loop from i < Math.floor(arr.length/size) to i < (Math.floor(arr.length/size) + 1).
This modified code then does not work for the first three conditions as it inserts an empty array element into the main array.


#2

Here is something to consider. Your iterator (i) does not have to increment by one (i++). You could, say, increment it by 3 by using i+=3 or i = i+3. You can take whatever size steps through the array you want.


#3

I think the issue is in the end condition of your for loop. The problem is that you are rounding down so if there are 2 and a half groups you need, you are only getting 2. Are you sure down is how you need to round?

To see what I mean, put a console.log into your code:

function chunkArrayInGroups(arr, size) {
  var newArray = [];
  console.log("we will run the for loop " + Math.floor(arr.length/size) + " times");
  for (var i = 0; i < Math.floor(arr.length/size); i++) {
    newArray[i] = arr.slice(size*i,size*(i+1));
  }
  return newArray;
}
chunkArrayInGroups();

Make sure it is going to run the number of times you want. I think you’ll find that whenever there isn’t some leftover array, it doesn’t run. Again, that can be fixed with how you round.

When I make the hinted at correction, it passes for me. Don’t get frustrated - a lot of people have a problem with this one. You’re almost there.


#4

Ah, got it! I didn’t need to round down the number.


#5

Cool.

If I have one frustration with helping new programmers (not that I’m complaining) it is a lack of debugging skills. When I tried out your code in codepen and it didn’t do what I wanted, the first thing I did was open up the browser console and looked for errors. There were none so the the next thing I do is put some console.log statements in to see if it was doing what I wanted. I saw that the for loop wasn’t running the correct number of times. That led me to the math. That’s why I added the console.log line that I did above - to see what was actually happening.

I have math problems I use when tutoring elementary school kids. One trap I often put in is, “If 10 students can go on the field trip and each car will hold 3 students, how many cars are needed?” It’s amazing how many kids will reflexively answer, “3 and a third!” Of course, you can’t have a third of a car. And you can’t round down because kids will get left behind.

So, I would want to know how rounding would affect those loops. Let’s take a look:

var numStudents = 10;
var spacesPerCar = 3;

var carsNeeded = numStudents/spacesPerCar;

console.log("carsNeeded = " + carsNeeded);

console.log("\n\n\nRunning with rounding down ...");
for (var i = 0; i < Math.floor(carsNeeded); i++) {
  console.log("putting kids in car " + (i+1));
}

console.log("\n\n\nRunning with the rounding up ...");
for (var i = 0; i < Math.ceil(carsNeeded); i++) {
  console.log("putting kids in car " + (i+1));
}

console.log("\n\n\nRunning with no rounding ...");
for (var i = 0; i < carsNeeded; i++) {
  console.log("putting kids in car " + (i+1));
}

When we look at the output, obviously the last two give us correct answers. Which is better? I like the rounding up because it is clearer. With no rounding, I have to stop and think : How does JS handle a floating point number in a for loop? I guess it makes sense, since 3 is less than 3.3333333. But I would probably round it up just for clarity.


#6

I’m trying to understand the explanation given for advanced code solution 2 in the answer guide for this challenge: freeCodeCamp Algorithm Challenge Guide: Chunky Monkey.

The solution…

function chunkArrayInGroups(arr, size) {
 var newArr = [];
 while (arr.length) {
   newArr.push(arr.splice(0,size));
 }
 return newArr;
}

…seems to be missing a step or two. Can I assume that if the condition in the while loop is arr.length, then JavaScript knows from the initial splice size how big each subsequent splice should be?


#7

Yeah, debugging is a skill I have yet to master. Your example is helpful.


#8

The “magic” behind this version is the arr.splice part. See here for more information about what splice does to an array. Splice can modify the original array (which is what is done in the advanced version).


#9

With regards to the solution you don’t understand, I recommend you figure it out yourself. Put console.log statements in there.

function chunkArrayInGroups(arr, size) {
 var newArr = [];
 while (arr.length) {
   console.log("\n\n\nIn while loop, arr.length is " + arr.length);
   console.log("Before slice and push, arr is...");
   console.log(arr);
   console.log("Before slice and push, newArr is...");
   console.log(newArr);
   newArr.push(arr.splice(0,size));
   console.log("After slice and push, arr is...");
   console.log(arr);
   console.log("After slice and push, newArr is...");
   console.log(newArr);
   console.log("At end of loop, arr.length is " + arr.length);
 }
 return newArr;
}

chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6, 7, 8], 4);

Run this in a codepen or whatever and see what happens. Study the output, step through it. This is how I figure things out. You’ll learn much more by tracing though this yourself.

Be inquisitive. Test, test, test if you aren’t sure about something. Learn to investigate.

The only thing I’d add is to remember that 0 evaluates as false.


#10

I was able to debug my code with console.log statements today. What an empowering feeling.