Home > Net >  Chunk an array of objects and add empty arrays at the end
Chunk an array of objects and add empty arrays at the end

Time:07-28

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;
}

  • Related