I was looking through the You Don't Need Lodash repo and I decided to take a crack at making my own _.chunk function.
// === sample 1 ===
// I think this is clear and avoids mutable data. The basic idea is:
// 1. make a new sub array when you need a new sub array
// 2. keep the old stuff and add the new thing to the end
const chunk = (input, size) => {
return input.reduce((arr, item, idx) => {
return idx % size === 0
? [...arr, [item]]
: [...arr.slice(0, -1), [...arr.slice(-1)[0], item]];
}, []);
};
// === sample 1.2 ===
// I think this is a slightly clearer way to state that you need a new sub array
const chunk = (input, size) => {
return input.reduce((arr, item, idx) => {
return arr.length === 0 || arr.slice(-1)[0].length === size
? [...arr, [item]]
: [...arr.slice(0, -1), [...arr.slice(-1)[0], item]];
}, []);
};
// === sample 1.3 ===
// Naming the sub array might be most clear.
const chunk = (input, size) => {
return input.reduce((arr, item) => {
const subArr = arr.slice(-1)[0];
return arr.length === 0 || subArr.length === size
? [...arr, [item]]
: [...arr.slice(0, -1), [...subArr, item]];
}, []);
};
// === sample 2 ===
// I think this is also clear, but uses mutable data. The basic idea is:
// 1. fill a sub array
// 2. when a sub array is full, create a new sub array and append it to the
// main array
const chunk = (input, size) => {
return input.reduce(({arr, subArr}, item) => {
if (subArr === undefined || subArr.length === size) {
subArr = [item];
arr.push(subArr);
} else {
subArr.push(item);
}
return {arr, subArr};
}, {arr: [], subArr: undefined}).arr;
};
// === sample 2.1 ===
// Here's the same function as sample 2 using a loop
const chunk = (input, size) => {
const arr = [];
let subArr = [];
for (item of input) {
if (arr.length === 0 || subArr.length === size) {
subArr = [item];
arr.push(subArr);
} else {
subArr.push(item);
}
}
return arr;
};
// === sample 3 ===
// Here's a mathy version. I'm not a fan since it's harder to explain this in a
// simple way.
function chunk(input, size) {
var arr = [];
for (var idx = 0; idx < input.length; idx++) {
var item = input[idx];
var newIdx = Math.floor(idx / size);
var newSubIdx = idx - newIdx * size;
if (idx % size === 0) arr[newIdx] = [];
arr[newIdx][newSubIdx] = item;
}
return arr;
}
I think my favorite is sample 1.3 since it avoids mutable data and is clear to me. Which function would you use? Would you make your own?
Edit: I had a mistake in my initial code when I didn't handle when arr.length === 0
in this code arr.length === 0 || subArr.length === size
. This makes the samples slightly less nice, but still relatively clear in my opinion.
Top comments (0)