Search code examples
javascriptarraysarraylistecmascript-5

How to batch group of array elements in reference to another array of group size?


How to batch group of array elements in reference to another array of group size ? I tried below code.

Code:

var group_size = [1, 3, 5];
var elements = ['a','b','c','d','e','f','g','h','i','j','k','l'];
        
var output = [];
    for (var i=0; i < group_size.length; i++) {
    output.push(elements.slice(i, group_size[i]))
}
console.log(output);

Output:

[["a"], ["b", "c"], ["c", "d", "e"]]

But expected output:

[['a'], ['b','c','d'],['e','f','g','h','i'],['j','k','l']]

If there are moe elements, then those elements to be grouped by max group_size element.

Example :

Input = ['a','b','c']
Output = [['a'], ['b','c']]

Input = ['a','b','c','d','e']
Output = [['a'], ['b','c','d'], ['e']]

Input = ['a','b','c','d','e','f','g','h','i','j','k','l']
Output = [['a'], ['b','c','d'],['e','f','g','h','i'],['j','k','l']]

Input = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p']
Output = [['a'], ['b','c','d'],['e','f','g','h','i'],['j','k','l','m','n'], ['o','p']]

I tried above code but that's limiting. How can I do it in ecma5 (js) ?


Solution

  • What do you need for the solution:

    1. Keep a track of the largest group length.
    2. Keep a track of the offset at which the next group should start.
    3. Slice groups while they are within the range of the source array.
    4. If the array is larger than the sum of all groups, continue slicing chunks equal to the length of the largest group.

    function splitIntoGroups (array, groups) {
        let output = [];
        let maxLength = 1;
        for (var i=0, offset=0; i < groups.length && offset < array.length; i++) {
            output.push(array.slice(offset, offset + groups[i]));
            offset += groups[i];
            maxLength = Math.max(maxLength, groups[i]);
        }
        while (offset < array.length) {
            output.push(array.slice(offset, offset + maxLength));
            offset += maxLength;
        }
        return output;
    }
    
    let elements = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'];
    let groups = [1, 3, 5, 5, 5, 1000];
    
    // when sum of all groups exceeds the source array,
    // they are truncated to match the array
    console.log(splitIntoGroups(elements.slice(0, 3), groups));
    console.log(splitIntoGroups(elements.slice(0, 5), groups));
    console.log(splitIntoGroups(elements.slice(0, 12), groups));
    console.log(splitIntoGroups(elements, groups));
    
    // when sum of all groups doesn't exceed the source array,
    // the largest group is repeated until the end of the array
    console.log(splitIntoGroups(elements, [1, 3, 5]));