Splitting a JS array into N arrays
I think this way using splice is the cleanest:
splitToChunks(array, parts) {
let result = [];
for (let i = parts; i > 0; i--) {
result.push(array.splice(0, Math.ceil(array.length / i)));
}
return result;
}
For example, for parts = 3
, you would take 1/3, then 1/2 of the remaining part, then the rest of the array. Math.ceil
ensures that in case of uneven number of elements they will go to the earliest chunks.
(Note: this destroys the initial array. To avoid that, you can use its temporary shallow copy instead: const copiedArray = [ ...originalArray ]
)
You can make the slices "balanced" (subarrays' lengths differ as less as possible) or "even" (all subarrays but the last have the same length):
function chunkify(a, n, balanced) {
if (n < 2)
return [a];
var len = a.length,
out = [],
i = 0,
size;
if (len % n === 0) {
size = Math.floor(len / n);
while (i < len) {
out.push(a.slice(i, i += size));
}
}
else if (balanced) {
while (i < len) {
size = Math.ceil((len - i) / n--);
out.push(a.slice(i, i += size));
}
}
else {
n--;
size = Math.floor(len / n);
if (len % size === 0)
size--;
while (i < size * n) {
out.push(a.slice(i, i += size));
}
out.push(a.slice(size * n));
}
return out;
}
///////////////////////
onload = function () {
function $(x) {
return document.getElementById(x);
}
function calc() {
var s = +$('s').value, a = [];
while (s--)
a.unshift(s);
var n = +$('n').value;
$('b').textContent = JSON.stringify(chunkify(a, n, true))
$('e').textContent = JSON.stringify(chunkify(a, n, false))
}
$('s').addEventListener('input', calc);
$('n').addEventListener('input', calc);
calc();
}
<p>slice <input type="number" value="20" id="s"> items into
<input type="number" value="6" id="n"> chunks:</p>
<pre id="b"></pre>
<pre id="e"></pre>
function split(array, n) {
let [...arr] = array;
var res = [];
while (arr.length) {
res.push(arr.splice(0, n));
}
return res;
}