Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

218
Vistas
How to group and count an array of objects

I am trying to create a stacked bar graph, but I can't figure out how to reshape my data.

The data coming from the backend looks something like below, where it has a date and some category key

[
    {date: 'January', category: 'A'},
    {date: 'January', category: 'B'},
    {date: 'February', category: 'A'},
    {date: 'February', category: 'B'},
    {date: 'February', category: 'C'},
    {date: 'February', category: 'B'},
    ...
]

I need to reshape this data into the form like below, where it will group them into their respective months, and then count the number of times each category was seen

[
    {name: 'January', countA: 1, countB: 1, countC: 0 },
    {name: 'February', countA: 1, countB: 2, countC: 1 }
    ...
]

So far, I've only been able to count the total number of categories per month using the reduce function such as

const filterData = data.reduce((groups, curr) => {
    const {January = 0, February = 0, ...} = groups;
    switch(curr.date){
        case 'January': return {...groups, January: January + 1}
        case 'February': return {...groups, February: February + 1}
        ...
    }
}, {})

But this won't work for the stacked bar graph.

about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

You can use Array#reduce with an object to store the counts for each month.

let arr = [
    {date: 'January', category: 'A'},
    {date: 'January', category: 'B'},
    {date: 'February', category: 'A'},
    {date: 'February', category: 'B'},
    {date: 'February', category: 'C'},
    {date: 'February', category: 'B'},
];
let res = Object.values(arr.reduce((acc, {date, category})=>{
    ++(acc[date] ??= {date, countA: 0, countB: 0, countC: 0})['count' + category];
    return acc;
}, {}));
console.log(res);

about 4 years ago · Juan Pablo Isaza Denunciar

0

Based on your question we can't really be sure there will be only three categories so here's a solution that will deal with n number of them. It's longer than you may want but hopefully not too verbose. (I've used a for...of loop instead of reduce at the end but you can swap them if you want.)

const data = [
  {date: 'March', category: 'Z'},
  {date: 'January', category: 'A'},
  {date: 'January', category: 'B'},
  {date: 'February', category: 'A'},
  {date: 'November', category: 'D'},
  {date: 'February', category: 'M'},
  {date: 'February', category: 'B'},
  {date: 'February', category: 'C'},
  {date: 'February', category: 'B'},
  {date: 'January', category: 'D'}
];

// Create a deduped array of elements with
// a `count[letter]` format by creating
// a Set of mapped categories
const catArr = new Set(data.map(obj => {
  return `count${obj.category}`;
}));

// Create a new counts object from the set
// setting each count property to 0
const counts = {};
for (const count of catArr) {
  counts[count] = 0;
}

// Iterate over the data. If the date key isn't
// on the output object, add it and set it where
// one of the properties is the date, and the others
// are a copy of the categories
const out = {};
for (const obj of data) {
  const { date, category } = obj;
  const count = `count${category}`;
  out[date] = out[date] || { name: date, ...counts };
  ++out[date][count];
}

// Get the values of the output object
console.log(Object.values(out));

about 4 years ago · Juan Pablo Isaza Denunciar

0

Since the other answers have covered approaches using reduce and for...of, I'll add another approach that is pretty straightforward, using forEach.

More on forEach here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

let months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
let cleanData =[];
let dirtyData = [];

// get original data
dirtyData = getData();

// iterate through each month
months.forEach(month => {
    let monthEntries = dirtyData.filter( e => e.date == month);
    let aCount = 0;
    let bCount = 0;
    let cCount = 0;

    // for each month, count how many enteries there were in each category
    monthEntries.forEach(e => {
        switch (e.category.toLowerCase()){
            case "a":
                aCount++;
                break;
            case "b":
                bCount++;
                break;
            case "c":
                cCount++;
                break;
        }
    });

    // push the data to a new cleanData array in our preferred format
    cleanData.push({name: month, countA: aCount, countB: bCount, countC: cCount})
});

// log results
console.log(cleanData);

// function to retreive original data
function getData() { return [
    {date: 'January', category: 'A'},
    {date: 'January', category: 'B'},
    {date: 'February', category: 'A'},
    {date: 'February', category: 'B'},
    {date: 'February', category: 'C'},
    {date: 'March', category: 'B'},
    {date: 'March', category: 'A'},
    {date: 'March', category: 'B'},
    {date: 'March', category: 'C'},
    {date: 'March', category: 'B'},
    {date: 'April', category: 'A'},
    {date: 'April', category: 'B'},
    {date: 'April', category: 'C'},
    {date: 'April', category: 'B'},
    {date: 'May', category: 'A'},
    {date: 'May', category: 'B'},
    {date: 'May', category: 'C'},
    {date: 'May', category: 'B'},
    {date: 'May', category: 'A'},
    {date: 'May', category: 'B'},
    {date: 'May', category: 'C'},
    {date: 'May', category: 'B'},
    {date: 'May', category: 'A'},
    {date: 'May', category: 'B'},
    {date: 'June', category: 'C'},
    {date: 'June', category: 'B'},
    {date: 'June', category: 'A'},
    {date: 'July', category: 'B'},
    {date: 'July', category: 'C'},
    {date: 'July', category: 'B'},
    {date: 'July', category: 'A'},
    {date: 'July', category: 'B'},
    {date: 'August', category: 'C'},
    {date: 'September', category: 'B'},
    {date: 'September', category: 'A'},
    {date: 'September', category: 'B'},
    {date: 'October', category: 'C'},
    {date: 'October', category: 'B'},
    {date: 'October', category: 'A'},
    {date: 'October', category: 'B'},
    {date: 'November', category: 'C'},
    {date: 'November', category: 'A'},
    {date: 'December', category: 'B'},
    {date: 'December', category: 'B'},
];
}

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda