Search code examples
javascriptarraysobjectreduce

Javascript grouping


  • How can I add data by grouping with country label and create data array that has 12 index indicating months and containing value of data before grouping. I need help, how to push and group the data according to the month number. e.x
arr = [
  { label: 'US', data: '10', monthNumber: 1 },
  { label: 'US', data: '2', monthNumber: 3  },
  { label: 'US', data: '60', monthNumber: 2  },
  { label: 'UK', data: '10', monthNumber: 5 },
  { label: 'SA', data: '1', monthNumber: 1  },
  { label: 'CA', data: '70', monthNumber: 1  },
  { label: 'SA', data: '10', monthNumber: 12 },
];

now i need the results to be like

[
  { label: 'US', data: [10,60,2,0,0,0,0,0,0,0,0,0] },
  { label: 'UK', data: [0,0,0,0,10,0,0,0,0,0,0,0] },
  { label: 'SA', data: [1,0,0,0,0,0,0,0,0,0,0,10] },
  { label: 'CA', data: [70,0,0,0,0,0,0,0,0,0,0,0] },
];

Solution

  • Create a new object by reducing over the array using the labels as object keys, and initialising the property value as an object with a label, and a pre-filled array of zeros. Then update the array with the data at the relevant position.

    const arr=[{label:"US",data:"10",monthNumber:1},{label:"US",data:"2",monthNumber:3},{label:"US",data:"60",monthNumber:2},{label:"UK",data:"10",monthNumber:5},{label:"SA",data:"1",monthNumber:1},{label:"CA",data:"70",monthNumber:1},{label:"SA",data:"10",monthNumber:12}];
    
    function grouper(arr) {
    
      // `reduce` over the array passing in an
      // empty object as the initial accumulator value
      const out = arr.reduce((acc, c) => {
    
        // Destructure the properties from the current
        // iterated object
        const { label, data, monthNumber } = c;
    
        // If the label doesn't exist as a key on the object
        // create it, and assign an object as its value, using
        // the label, and adding a pre-filled array of zeros to
        // its data property
        acc[label] ??= { label, data: new Array(12).fill(0) };
    
        // Update the data array with the data value at the
        // appropriate position
        acc[label].data[monthNumber - 1] = Number(data);
    
        // Return the accumulator for the next iteration
        return acc;
    
      }, {});
    
      // Finally get the array of updated objects
      // from the accumulated data
      return Object.values(out);
      
    }
    
    console.log(grouper(arr));

    Additional documentation