Digamos que tengo una serie de objetos:

[
    {
        category: 'Category A',
        mainUnits: 5,
        subUnits: 3
    },

    {
        category: 'Category A',
        mainUnits: 9,
        subUnits, 12
    },

    {
        category: 'Category B',
        mainUnits: 4,
        subUnits, 6
    },

    {
        category: 'Category B',
        mainUnits: 2,
        subUnits, 4
    }
]

Sin embargo, parece que no puedo obtener una matriz que se vea así:

[
    {
        category: 'Category A',
        mainUnits: 14,
        subUnits: 15
    },

    {
        category: 'Category B',
        mainUnits: 6,
        subUnits: 10
    }
]

He podido hacer algún tipo de avance, pero no puedo obtener el resultado exacto que necesito. Cualquier orientación es muy apreciada, ¡gracias!

3
Lushmoney 28 feb. 2018 a las 03:10

3 respuestas

La mejor respuesta

El método de matriz .reduce parece encajar bien aquí.

Use el método de matriz .find para ver si ya hay un elemento con esa categoría en el resultado. Si es así, agregue los campos, pero si no, agregue el elemento al resultado:

const input = [{
  category: 'Category A',
  mainUnits: 5,
  subUnits: 3
}, {
  category: 'Category A',
  mainUnits: 9,
  subUnits: 12,
}, {
  category: 'Category B',
  mainUnits: 4,
  subUnits: 6,
}, {
  category: 'Category B',
  mainUnits: 2,
  subUnits: 4,
}];

const result = input.reduce((result, item) => {
  const existing = result.find(x => x.category === item.category);
  if (existing) {
    existing.mainUnits += item.mainUnits;
    existing.subUnits += item.subUnits;
  } else {
    result.push(item);
  }

  return result;
}, []);

console.log(result);
7
CRice 28 feb. 2018 a las 00:14

La respuesta de @ CRice es excelente, pero aquí hay otro enfoque si desea:

const input = [{
  category: 'Category A',
  mainUnits: 5,
  subUnits: 3
}, {
  category: 'Category A',
  mainUnits: 9,
  subUnits: 12
}, {
  category: 'Category B',
  mainUnits: 4,
  subUnits: 6
}, {
  category: 'Category B',
  mainUnits: 2,
  subUnits: 4
}];

let sums = {};
for (let entry of input) {
  sums[entry.category] = sums[entry.category] || {
    mainUnits: 0,
    subUnits: 0
  };
  sums[entry.category].mainUnits += entry.mainUnits;
  sums[entry.category].subUnits += entry.subUnits;
}

const result = Object.keys(sums).map(category => Object.assign({
  category
}, sums[category]));

console.log(result);
5
Jeto 4 oct. 2018 a las 09:13

Necesita una función como esta:

function catTotals(catsArray){
  var cats = [], totals = [];
  for(var i=0,ca,c,o,x,l=catsArray.length; i<l; i++){
    ca = catsArray[i]; c = ca.category; x = cats.indexOf(c);
    if(x === -1){
      cats.push(c); totals.push({category:c, mainUnits:ca.mainUnits, subUnits:ca.subUnits});
    }
    else{
      o = totals[x]; o.mainUnits += ca.mainUnits; o.subUnits += ca.subUnits;
    }
  }
  return totals;
}
var cats = [
    {
        category: 'Category A',
        mainUnits: 5,
        subUnits: 3
    },

    {
        category: 'Category A',
        mainUnits: 9,
        subUnits: 12
    },

    {
        category: 'Category B',
        mainUnits: 4,
        subUnits: 6
    },

    {
        category: 'Category B',
        mainUnits: 2,
        subUnits: 4
    }
]
console.log(catTotals(cats));
1
StackSlave 28 feb. 2018 a las 01:05