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>