Reputation: 133
I have an array
const myArray = [1, 2, 2, 2, 3, 3, 3, 4, 4, 4];
that I want to split into smaller arrays. I am using lodash chunk to do it.
_.chunk(myArray, 3);
this will return
[1, 2, 2], [2, 3, 3], [3, 4, 4], [4]
but I would like it to return
[1], [2, 2, 2], [3, 3, 3], [4, 4, 4]
my solution was this
_.chain(myArray).reverse().chunk(3).reverse().value()
it reverses the array, splits it and then reverses it again. But is there a better way to do this? So chunk starts from the end and not the start.
Upvotes: 3
Views: 2811
Reputation: 191986
Find the remainder, and if there's remainder, slice it from the left side, and combine it with the chunks of the rest of the array. If no remainder, chunk normally:
const myArray = [1, 21, 22, 23, 31, 32, 33, 41, 42, 43];
const chunkRight = (arr, size) => {
const rm = arr.length % size;
return rm ?
[arr.slice(0, rm), ..._.chunk(arr.slice(rm), size)]
:
_.chunk(arr, size);
};
const result = chunkRight(myArray, 3);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
Upvotes: 4
Reputation: 33726
An alternative could be using the function reduceRight
.
const myArray = [1, 2, 2, 2, 3, 3, 3, 4, 4, 4];
const chunks = myArray.reduceRight((a, n, i, arr) => {
if (((arr.length - 1) - i) % a.chunk === 0) {
a.current = [];
a.chunks.unshift(a.current);
}
a.current.push(n);
return a;
}, {
/*This is the size per chunk*/chunk: 3,
/*The array with the chunks*/ chunks: [],
/*The current array which is being filled*/ current: []}).chunks;
console.log(chunks);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 370789
There's no built-in argument option for that (or separate method like chunkEnd
), but it's trivial to write something yourself that achieves the same thing without reverse
ing the array:
const chunkFromEnd = (arr, size) => {
const firstSize = arr.length % size;
const result = [arr.slice(0, firstSize)];
for (let i = firstSize; i < arr.length; i += size) {
result.push(arr.slice(i, i + size));
}
return result;
};
console.log(chunkFromEnd([1, 2, 2, 2, 3, 3, 3, 4, 4, 4], 3));
console.log(chunkFromEnd([1, 2, 2, 2, 3, 3, 3, 4, 9, 4, 4, 6, 2, 1], 3));
Upvotes: 1