skip to Main Content

I want to chunk an array into groups with the last few groups having the biggest size if the array cannot be divided evenly. Like the Euro Cup 2024 qualifiers where there are 53 teams divided into 10 groups with the last few groups having the biggest size (5x5x5x5x5x5x5x6x6x6). Here’s the code to chunk the array but it has the first few groups with biggest size [Fiddle] (6x6x6x5x5x5x5x5x5x5):

function partition(arr: Team[], group: number) {
  let rest = arr.length % group;
  let size = Math.floor(arr.length / group);
  let j = 0;
  return Array.from({ length: group }, (_, i) => {
    return arr.slice(j, (j += size + (i < rest ? 1 : 0)));
  });
}

let data = Array.from({length: 53}, (_,i) => i+1);
let result = partition(data, 10);
// result.reverse() is not ideal and would complicate things.
console.log(result);

Using reverse() to flip the result is not ideal in my case because some teams from the arr must be the first few groups. Ifreverse is used, these teams would be placed in the last few groups. Is there a way to chunk the array into something like this (5x5x5x5x5x5x5x6x6x6)?

4

Answers


  1. try the following add the extra members to the end of the group

    working example

    function partition(arr, group) {
      const totalLength = arr.length;
      const size = Math.floor(totalLength / group);
      const largerGroupCount = totalLength % group; // find how many groups are large
      const groups = [];
      let startIndex = 0;
    
      for (let i = 0; i < group; i++) {
        const currentGroupSize = size + (i >= group - largerGroupCount ? 1 : 0);
        groups.push(arr.slice(startIndex, startIndex + currentGroupSize));
        // update the index for the next group
        startIndex += currentGroupSize;
      }
    
      return groups;
    }
    
    let data = Array.from({length: 53}, (_, i) => i + 1);
    let result = partition(data, 10);
    console.log(result);
    
    Login or Signup to reply.
  2. function partition(arr: Team[], group: number) {
      const rest = arr.length % group;
      const baseSize = Math.floor(arr.length / group);
      let j = 0;
      const result = Array.from({ length: group }, (_, i) => {
        const size = baseSize + (i < rest ? 1 : 0);
        const chunk = arr.slice(j, j + size);
        j += size;
        return chunk;
      });
      return result;
    }
    
    // Example usage:
    const data = Array.from({ length: 53 }, (_, i) => i + 1);
    const result = partition(data, 10);
    console.log(result);
    
    Login or Signup to reply.
  3. Here’s an approach that just splices off groups from the input array, and uses the current index to determine whether an additional team needs to be added to a group.

    type Team = string;
    
    function partition(teams: Team[], groups: number) {
      const size = Math.floor(teams.length / groups);
      const rest = teams.length % groups;
      
      return Array.from(
        { length: groups },
        (_, i) => teams.splice(0, size + (rest >= groups - i ? 1 : 0))
      );
    }
    
    const data = Array.from({ length: 53 }, (_, i) => `Team ${i+1}`);
    const result = partition(data, 10);
    
    console.log(result);
    

    Playground link.

    This prevents you from having to keep track of the current index in a variable outside of the callback function. It does modify the input array, so if that is an issue, you’d probably want to copy the array (e.g. const data = [...teams];) first.

    Login or Signup to reply.
  4. You need just a small fix here, instead of i < rest do group - i <= rest (to make groups bigger in the end of the group array):

    function partition(arr: Team[], group: number) {
      let rest = arr.length % group;
      let size = Math.floor(arr.length / group);
      let j = 0;
      return Array.from({ length: group }, (_, i) => {
        return arr.slice(j, (j += size + (group - i <= rest ? 1 : 0)));
      });
    }
    
    let data = Array.from({length: 53}, (_,i) => i+1);
    let result = partition(data, 10);
    // result.reverse() is not ideal and would complicate things.
    result.forEach(r => console.log(...r));
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search