# Basic Algorithm Scripting: Chunky Monkey question

This was someone’s solution which I liked because it seems the most straightforward! However I am just wondering why the final expression is omitted in the for loop and what difference it makes if it is there?

Will it still increment up the array anyway even if the final expression isn’t there?

How does it know to make the second new array start at ‘c’ and not ‘b’? ie. ending up like [“a”, “b”], [“b”, “c”], [“c”, “d”]

``````function chunkArrayInGroups(arr, size) {

var newArr = [];
for (var i = 0; i < arr.length;)
newArr.push(arr.splice(i, size));

return newArr;
}

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

You don’t want the `return` statement inside the loop because function execution ends when a `return` statement is hit. If that last line was inside the `for` loop, it would end the loop after pushing only once.

2 Likes

For what its worth, this style isn’t great.

Here is the code with a nicer style. You really want to use a while loop here.
`for (let i = 0; i < arr.length;))` is bad form for two reasons:

1. You want to explicitly include an iteration update (even if there isn’t one)
2. If you aren’t updating your iterator, then you almost certainly don’t want a `for` loop

In this code below, the `splice` actually removes `size` elements from the array `arr`, starting at index `0`.

``````// ----------------------------------------------------------
// While loop version
// ----------------------------------------------------------
function chunkArrayInGroups(arr, size) {
let newArr = [];

// Splice array into chunks
while (arr.length) {
newArr.push(arr.splice(0, size));
}

// Return result
return newArr;
}

// ----------------------------------------------------------
// Output while loop version
// ----------------------------------------------------------
console.log("----- While loop version -----");
console.log("Here we use arr.splice(start, size)");
console.log(chunkArrayInGroups(["a", "b", "c", "d"], 2));
``````

In this example, `size = 2`. Inside the first `while` loop iteration, the first two elements, `[a, b]`, are removed. The array `arr` still has elements, so `arr.length` is still truthy and we remove the new first two elements `[c, d]`. Now the array `arr` is empty and `arr.length` is falsey, so the loop ends and the new array `newArr` is returned.

This version of the code is better. You don’t want to change input arrays if you can avoid it.

``````// ----------------------------------------------------------
// For loop version
// ----------------------------------------------------------
function chunkArrayInGroups(arr, size) {
let newArr = [];

// Slice array into chunks
for (let i = 0; i < arr.length; i += size) {
newArr.push(arr.slice(i, i + size));
}

// Return result
return newArr;
}

// ----------------------------------------------------------
// Output for loop version
// ----------------------------------------------------------
console.log("----- For loop version -----");
console.log("Here we use arr.slice(start, stop)");
console.log(chunkArrayInGroups(["a", "b", "c", "d"], 2));
``````

In this example, again `size = 2`. Inside the first `for` loop iteration, we slice out the elements from `0` to `2`, `[a, b]`, and copy them into the new array. We then increment our iterator by `size`. `i` is now `2`, which is still not past the end of the array, and we slice out the elements from `2` to `4`, `[c, d]`, and copy them into the new array. On the next iteration, `i` is no longer less than the length of the original array, so the loop ends and the new array `newArr` is returned.

Also, indentation and braces are your friend. They keep your code clearer and better organized.

2 Likes

Thank you so much for your thorough explanation! That helped a lot.
I find that I can’t tell the difference between good form / style and bad form / style … do you have any tips for improving this, or will I just be able to improve gradually through practice and experience?

One question: What is an input array? Could you give an example in the code?

Thank you again.

What Jeremy means by “input array” is the array that your function was passed as an argument. To be more general, when you are iterating over a collection (an array, object, list etc) it is almost never a good idea to be changing that collection. You can do it, if you’re careful, but it is so easy to write infinite loops or to create bugs that are hard to track down.

As Jeremy pointed out, if you do plan on taking the approach of “keep removing parts of the array until it’s gone”, a `while` loop is a better tool for the job.

2 Likes

Honestly, a big part of how I’ve learned bad vs good style is having people point out how I can code something up better. Just like it took you a while to use English in the ways everyone expects, it’s takes time to learn how to ‘speak’ code.

When I have a function

``````foo(baz) {
...
return blarg;
}
``````

the agrument `baz` is the input. I tend to say ‘the input array’ and the ‘output array’ when I am dealing with a generic function that takes in an array and outputs an array to help distinguish which one I am referring to.

1 Like

(It’s worth noting that jargon varies depending on your background and community. Jeremy comes from a mathematics background and works mostly in C and Fortran. Every time I change jobs I encounter people who use slightly different terminology and for a while I feel lost even talking about things I actually understand. )

1 Like

So did you mean the while loop example you gave is changing the input array by using splice?
When you said ‘This version of the code is better’ - did you mean the while loop or the for loop you wrote underneath it? Sorry I am still confused!

The `.splice()` version modifies the input array. The correct way to use `.splice()` is with a `while` loop rather than a `for` loop.

But using `.slice()` and not modifying the input array is more typical. In this case you need to use a `for` loop.

In order of ‘goodness’ (measured by conforming to conventions/best practices):

1. `.slice()` and `for` (best practice)
2. `.splice()` and `while`
3. `.splice()` and `for`
1 Like

I see! Thanks for clarifying that

1 Like