I need to chunk an array of objects so i write:
function conditionalChunk(array, size, rules = {}) {
let copy = [...array],
output = [],
i = 0;
while (copy.length)
output.push(copy.splice(0, rules[i ] ?? size))
return output
}
and it works fine if I have rules like { 0: 2, 1: 2 }
const input = [[1,2,3],[4,5,6,7]],
output = conditionalChunk(input.flat(), 3, { 0: 2, 1: 2 });
// OUTPUT: [[1,2],[3,4],[5,6,7]]
but when I have rules at the end like { 0: 2, 1: 2, 2:0, 5:0 } my function ignore to create empty arrays at the end.
the output I need is:
const input = [[1,2,3],[4,5,6,7]],
output = conditionalChunk(input.flat(), 3, { 0: 2, 1: 2, 2:0, 5:0 });
// OUTPUT: [[1,2],[3,4],[],[5,6,7],[]]
so I just need to not ignore rules for empty arrays at the end of array. How I can do that?
CodePudding user response:
Finally, you could check the keys of rules
and if greater or equal to the next index of output
push an empty array.
function conditionalChunk(array, size, rules = {}) {
let output = [],
i = 0;
while (i < array.length)
output.push(array.slice(i, i = rules[output.length] ?? size));
let l = Object.keys(rules).reduce((l, v) => l (v >= output.length), 0);
while (l--) output.push([]);
return output;
}
console.log(conditionalChunk([1, 2, 3, 4, 5, 6, 7], 3, { 0: 2, 1: 2 })); // [[1,2],[3,4],[5,6,7]]
console.log(conditionalChunk([1, 2, 3, 4, 5, 6, 7], 3, { 0: 2, 1: 2, 2: 0, 5: 0 })); // [[1,2],[3,4],[],[5,6,7],[]]
console.log(conditionalChunk([1, 2, 3, 4, 5, 6, 7], 3, { 0: 0, 1: 2, 8: 0, 7: 0, 9:0, 20:0 }));
.as-console-wrapper { max-height: 100% !important; top: 0; }
CodePudding user response:
maybe you can try this, I prefer for...each
loop in place of a while
.
function conditionalChunk(array, size = 1, rules = {}) {
let copy = [...array],
output = [],
i = 0;
for (const rule of Object.keys(rules)) {
let val = copy.splice(0, rules[rule] || size);
if (typeof val === 'undefined') val = [];
output.push(val);
}
return output;
}
var results = conditionalChunk([1, 2, 3, 4, 5], 2, { 0:2, 1: 2, 2:2, 3:0 });
console.log(results, '::results::');
https://jsfiddle.net/5ozbj7na/
CodePudding user response:
A solution to your problem would be to add this bit of code after the while
loop before the return
statement
output.length = Math.max.apply(null, [output.length, ...Object.keys(rules)]) || output.length;
for (r in rules)
{
output[r] = new Array(rules[r]);
}
It just extends the output array to the desired length then populates required spots with empty arrays (sorry for the complicated first line but JavaScript is complicated so :| ...)
CodePudding user response:
Please try this one
function conditionalChunk(array, size, rules = {}) {
let copy = [...array],
output = [],
i = 0;
while (copy.length) output.push(copy.splice(0, rules[i ] ?? size));
const arr = Object.keys(rules).filter((key) => key > i);
arr.forEach((key) => {
if (rules[key] === 0) output.push([]);
});
return output;
}