Skip to content
Advertisement

Splitting an array in equal parts

I am looking for a Javascript Algorithm to split an array into chunks, but avoiding any small left overs. For example:

_.chunk([1, 2, 3, 4, 5, 6, 7], 3) // [[1, 2, 3], [4, 5, 6], [7]]

But I want this:

_.chunk([1, 2, 3, 4, 5, 6, 7], 3) // [[1, 2, 3], [4, 5], [6, 7]]

_.chunk([1, 2, 3, 4, 5, 6, 7], 4) // [[1, 2, 3, 4], [5, 6, 7]]

_.chunk([1, 2, 3, 4, 5, 6, 7], 5) // [[1, 2, 3, 4], [5, 6, 7]]

_.chunk([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3) // [[1, 2, 3], [4, 5, 6], [7, 8], [9, 10]]

So basically the output is spread over several arrays with a maximum number of elements passed in as second argument.

Advertisement

Answer

You should recalculate the size, which might need to be smaller than given. Then calculate from where the size should be one less for the remaining chunks.

So you will have potentially two different chunk sizes (which differ by 1). For both you can call the original _.chunk:

function chunk(arr, size) {
    const count = Math.ceil(arr.length / size);
    size = Math.ceil(arr.length / count);
    const i = arr.length-(size-1)*(arr.length%size && size-(arr.length%size));
    return _.chunk(arr.slice(0, i), size).concat(
           _.chunk(arr.slice(i), size-1));
}

for (let i = 1; i < 9; i++) {
    console.log(i, JSON.stringify(chunk([1, 2, 3, 4, 5, 6, 7], i)));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.4/lodash.min.js"></script>
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement