Bonfire: Chunky Monkey Solution

Ah, the Chunky Monkey. I’ve been, ever so gratefully, swamped with work (hooray!) But this Bonfire Solution has been a long time coming. I’ve been eyeing this one since I saw the name of it so let’s take a look at it. Unfortunately, it has very little to do with the Ben & Jerry’s ice cream flavor and a whole lot to do with Javascript arrays.

Here’s what Free Code Camp has provided us in this Bonfire:

function chunk(arr, size) {
  // Break it up.
  return arr;
}

chunk(["a", "b", "c", "d"], 2);

FCC wants us to split the array and group them into a multidimensional array based upon the size argument in the chunk() function call. Let’s get started.

Approaching the Problem

  1. First thing’s first, if I’m not already crystal clear on it, I’m going to have to define what a multidimensional array is and how JS makes things confusing and probably start an empty one to fill in later with my return values.
  2. I’ll have to approach the array splitting in one of two ways. I can use split() or I can use splice(). Whichever one I end up with, it’s going to have to be approached in the form of a loop and be based on whatever number falls into that second function argument.

The Different Flavors of Arrays

Arrays come in different types, and in various programming languages you might see support for more array types or less. Now, we’ve been working with arrays a lot with these Bonfires, and in this one FCC wants us to create a multidimensional array. I don’t spend days pondering the intricacies of JS arrays, so I might not have the most definitive answers for you. You can check out the MDN page on arrays for more information. For the rest of us just learning, here’s a simple rundown:

Associative Arrays – Are arrays that use strings instead of numbers to act as a “key” in the key value pair. For example:

// create an empty array called myCar.
var myCar = [ ];
// populate the myCar array with key value pairs.
myCar['color'] = 'red';
myCar['type'] = 'sedan';
myCar['make'] = 'Honda';
myCar['year'] = 2010;

In the above code, we created an associative array called myCar. Then we go on to populate it with values using keys to identify them. For example in the declaration: myCar[‘color’] = ‘red’, ‘color’ is considered the key and ‘red’ is the value. So when you need to reference the value red, you would use the key to call it up:

console.log (myCar['color']);

Seeing an associative array at work, it’s hard not to see how similar in function it is to a regular old object. Which is why some programmers recommend that instead of using JS’ associative arrays which can be confusing and aren’t seen all that often, you just create an object instead. It’s easier to understand, and you can do more with it and more efficiently. Here’s the same thing as what you saw above, except we use objects instead:

// create an object using object literal notation and call it myCar then populate it with properties.
var myCar = {
color : 'red',
type : 'sedan',
make : 'Honda',
year : 2010
}

And to get at the color for the myCar object, you would also use the key to call it up:

console.log (myCar['color']);

So that’s Associative Arrays, long story short, objects are easier and faster to work with. But what about Multidimensional Arrays?

Multidimensional Arrays – Are arrays within arrays. So technically, a multidimensional array can hold other arrays inside of itself. For example:

var myDesserts = [
['carrot cake', 'chocolate cake', 'cheesecake'],
['apple pie', 'pumpkin pie', 'plum pie'],
['shortbread cookies', 'chocolate chip cookies', 'sugar cookies']
];

In the above code, we’ve created an array called myDesserts. Within the myDesserts array, it contains three elements. Each of those elements is an array that contains three values each. So if I wanted to access ‘plum pie’ in the above code, I’d have to call it up like this:

console.log (myDesserts[1][2]);

In the above code, I’m referencing the myDesserts multidimensional array, then telling it to go into the second array (we reference the number 1 to find the second array because JS starts counting at 0) and then give me the third value in that second array (we reference 2 to get the third value because 0 is ‘apple pie’ since JS starts counting at 0), which should be plum pie.

So now that we know what these two kinds of arrays are, let’s get back to our Bonfire, which is actually considerably simpler than all this talk about arrays.

Building the Solution with a While Loop

I’m going to use a While Loop for this chunky monkey challenge, but a For Loop will work just as well–it’s only a little more verbose and not really necessary. First thing I’m going to do is create my empty While Loop and my empty multidimensional array to push my values into:

function chunk (arr, size) {
var chunked = [];
while () {
}
return chunked;
}

The above code is just a skeleton of what I’m planning to do. But I’ve declared an empty array called chunked. Then set up an empty while loop that doesn’t do anything useful yet. And finally, I’m returning the chunked array. All stuff we should be really familiar with by now. Next thing I’m going to do is evaluate the length of arr. So that it will essentially run the loop and take care of all the values that arr might have fed into the function. This is what that will look like:

function chunk (arr, size) {
var chunked = [];
while (arr.length) {
}
return chunked;
}

Finally, I’m going to use a bunch of methods to perform two major things. I want to add values into an array where each array contains two values within it. This means we need a and b in one array and c and d in another, both of those arrays will have to go into my chunked array. What I’m going to use is a method called splice(). Hold onto your hats, we’re heading into another sidetrack.

The Splice() Method

Splice() is a handy method in Javascript that allows you to remove elements from an array and, if it pleases you, add elements back in. It can even return the removed elements. It has a couple of efficiency boosts over split() because with one splice(), you can both add, remove and return. Here’s splice() in action:

var myJams = ['Cranberry', 'Strawberry', 'Grape', 'Apple'];
myJams.splice(1, 3, 'Crabapple', 'Orange');

console.log(myJams);

In the above code, I declared an array called myJams, which originally contains four types of jams: Cranberry, Strawberry, Grape  and Apple. On the next line, I use the splice() method to select the start and end of where I want to do my splicing (start at position 1, end at position 3) and I designated two new values to add to the array: Crabapple and Orange.

The result when logged out will be: Cranberry, Crabapple, Orange. What splice did was remove the old values in myJams starting at position 1 (Strawberry) and ending on position 3 (Apple). Then it put Crabapple and Orange at the end of myJams. The two numbers in the arguments will give you the range of splicing, then what comes after is what you want to add in. So, I could very well have something like this instead:

var myJams = ['Cranberry', 'Strawberry', 'Grape', 'Apple'];
myJams.splice(1, 2, 'Crabapple', 'Orange', 'Plum', 'Banana', 'Pomegranate');

console.log(myJams);

And the log would reveal this list for myJams: Cranberry, Crabapple, Orange, Plum, Banana, Pomegranate, Apple. This is because I started at 1, but ended at 2 and pushed the remaining values into the place left open from where I removed those values. Therefore, instead of seeing the new values added at the end, they get placed into the middle spaces where the old values used to be.

Using splice, we can trim away the values from the array we don’t need and replace it with the values declared as the arr argument.

Solving the Chunky Monkey Challenge

Here’s the solution:

function chunk (arr, size) {

var chunked = [];
while (arr.length) {
chunked.push(arr.splice(0, size));
}

return chunked;
}

chunk(["a", "b", "c", "d"], 2);

We’ve already gone through the easy stuff, so let’s focus on the magic inside of the while loop. We’re checking to make sure that we loop through all values within the arr argument. So for each of those values, we go in and push to the chunked array each value in arr. For each of the arr values, we want to splice them. We start splicing at 0 and splice it using the value for size (which is 2 in this case). So each time we run through the splice, it knows that we want it all spliced, and to split things up into groups of two. This works well enough if you want groups of 3, 4, 5, etc. So long as you have the values and an appropriate size argument for each. Even if you don’t have enough values to feed into the function, it would still group as many as it can into groups and push the rest into an array. Give it a try with ten values, then push them into groups of 4 to see how it works. In the mean time, we’ve solved Free Code Camp’s Chunky Monkey Bonfire.

I had to do a lot of looking up and experimentation to get at the solution for this one, so check out some of the Resources I referenced for additional help and information.

Resources

Microsoft DN, Splice Method
For some reason, I found Microsoft DN’s explanation of splice() to be the easiest to understand so here it is.

MDN, Splice Method
Another resource for splice(), more detailed this time.

SharkySoft, Multidimensional Arrays Explanation
SharkySoft’s ultra-minimalist approach to design and development has put this particular page in a warm place within my heart. It’s also a great explanation of JS Multidimensional Arrays.


Posted

in

by

Comments

6 responses to “Bonfire: Chunky Monkey Solution”

  1. I had found another solution in the usual place which actually gave 3 solutions ranging from beginning to intermediate to advanced. I think you know what I’m referring to. In each case I always ran into at least one line of code or explanation of code that still didn’t connect the dots for me. But twice now I have looked at your explanations and they all make perfect sense.
    I also noticed that on that other page the advanced solution always used the least amount of code.

    Thanks so much for your passion not only as a programmer but as a teacher.

    1. Thank you so much for your kind words, Mark. 🙂

  2. Nicolas Pham-Dinh

    I want to clarify the role of the second parameter in splice(). Correct me if I am wrong, but the second parameter is not the ending position (or index), as it is in slice(), but rather the number, or range, of values we want to remove. For example:

    var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    array.splice(0,3); // [0, 1, 2]
    array.splice(1,3); // [1, 2, 3]
    array.splice(2,3); // [2, 3, 4]
    etc.

    1. Hi Nicolas, thanks for leaving a comment!

      If I understand your question correctly, then yes, the second parameter in splice() is the amount we want to remove. The second parameter in the solution in the post is pulling the parameter from the function chunk(). That parameter gets fed when chunk() is called.

  3. Hoa

    hi,
    Thanks for your super precise explanation. I just have some small questions.
    I’m sorry, I’m super noop in JS, so please forgive me if my questions are too dump. But according to what I’ve learnt, the while loop should be written in something like this:
    var n = 0;
    var x = 0;
    while (n < 3) {
    n++;
    x += n;
    }
    So if we declare "while (arr.length)", would it equal while(5) (is this case the length of my arr is 5), and would it become infinite loop? is there any reason for you to do it that way? because I tried to rewrite your but i became so weird. I hoped you would bother to give me the answer and thanks so much for your time.

    1. Hi Hoa,
      Sorry it’s taken so long to get back to you about this, I’ve been super busy. In case you’re still looking for a solution to your question: Yes, I believe it would cause an infinite loop if you were to replace n < 3 with arr.length in the while loop you posted. The reason this happens is because you are essentially saying while your array's length is equal to 5, then perform the loop. Since there's nothing in the loop itself that increments, decrements or modifies the value of 5 (or the value of your array), your while loop will be true forever which also means it'll run n++ and x+=n forever and ever. This will cause an infinite loop to occur.