-1

I have an array like this

[ { color: 'blue', type: '+', amount: '1' },
  { color: 'blue', type: '-', amount: '1' },
  { color: 'blue', type: '+', amount: '24' },
  { color: 'red', type: '+', amount: '10' },
  { color: 'red', type: '-', amount: '1' },
  { color: 'red', type: '-', amount: '1' },
  { color: 'red', type: '-', amount: '2' } ]

and I would like to group by color and type, and sum the amount. The result should be like this:

[ { color: 'blue', type: '+', amount: '25' },
  { color: 'blue', type: '-', amount: '1' },
  { color: 'red', type: '+', amount: '10' },
  { color: 'red', type: '-', amount: '4' } ]

Is there a good/right way to do this?

M. Twarog
  • 2,418
  • 3
  • 21
  • 39
nbar
  • 6,028
  • 2
  • 24
  • 65

2 Answers2

0

You can do it using reduce method:

and the code looks like this:

const data = [
       { color: 'blue', type: '+', amount: '1' },
       { color: 'blue', type: '-', amount: '1' },
       { color: 'blue', type: '+', amount: '24' },
       { color: 'red', type: '+', amount: '10' },
       { color: 'red', type: '-', amount: '1' },
       { color: 'red', type: '-', amount: '1' },
       { color: 'red', type: '-', amount: '2' }
    ];

    
    const result = [...data.reduce((r, o) => {
      
      const key = o.type + '-' + o.color;
    
      const item = r.get(key) || Object.assign({}, o, {
          amount: 0
      });
    
      item.amount += +o.amount;
    
      return r.set(key, item);
    }, new Map).values()];
    
    console.log(result);
Shankar
  • 2,890
  • 3
  • 25
  • 40
StepUp
  • 36,391
  • 15
  • 88
  • 148
0

Using a combination or Array#reduce and Map can solve this problem.

Use the color and type as an idea.

This could probably be simplified more

const data = [ { color: 'blue', type: '+', amount: '1' },
  { color: 'blue', type: '-', amount: '1' },
  { color: 'blue', type: '+', amount: '24' },
  { color: 'red', type: '+', amount: '10' },
  { color: 'red', type: '-', amount: '1' },
  { color: 'red', type: '-', amount: '1' },
  { color: 'red', type: '-', amount: '2' } ];
  
const reduced = data.reduce((acc,{color, type, amount})=>{
  const amountNum = Number(amount);
  const key = `${color}:${type}`;
  if(acc.has(key)){
    const old = acc.get(key);
    return acc.set(key, {color, type, amount: amountNum + old.amount});
  }
  return acc.set(key, {color, type, amount: amountNum});
}, new Map());

const res = Array.from(reduced).map(([,item])=>item);

console.log(res);
kemicofa ghost
  • 16,349
  • 8
  • 82
  • 131