Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sum of Javascript value if two conditions are met [duplicate]

Below is a code that adds the amount if the CategoryId is the same and creates a new line item per CategoryId.

self.OriginalLineItems = [
    { CategoryId: 'Cat1', Amount: 15, Type: 'TypeA' },
    { CategoryId: 'Cat1', Amount: 30, Type: 'TypeA' },
    { CategoryId: 'Cat1', Amount: 20, Type: 'TypeB' },
    { CategoryId: 'Cat2', Amount: 10, Type: 'TypeA' },
    { CategoryId: 'Cat2', Amount: 5, Type: 'TypeB' }]

self.newLineItems = [];

self.OriginalLineItems.forEach(function (o) {
    if (!this[o.CategoryId]) {
        this[o.CategoryId] = { CategoryId: o.CategoryId, Amount: 0, Type: o.Type };
        self.newLineItems.push(this[o.CategoryId]);
    }
    this[o.CategoryId].Amount += o.Amount;
}, Object.create(null));

Which would result in the array below:

self.newLineItems = [{ CategoryId: 'Cat1', Amount: 65, Type: 'TypeA' }, 
                     { CategoryId: 'Cat2', Amount: 15, Type: 'TypeA' }]

But I want to add a new condition which is Type, How do I get the results below?

self.newLineItems = [{ CategoryId: 'Cat1', Amount: 45, Type: 'TypeA' }, 
                     { CategoryId: 'Cat1', Amount: 20, Type: 'TypeB' }, 
                     { CategoryId: 'Cat2', Amount: 10, Type: 'TypeA' }, 
                     { CategoryId: 'Cat2', Amount: 5, Type: 'TypeB' }]

I could not find a solution on the linked question.

like image 644
Len Avatar asked Mar 08 '19 06:03

Len


1 Answers

You can use reduce(), findIndex() and every() to do that.

  1. In reduce() set accumulator to [].
  2. Then use findIndex() to find the Object in ac for which all the keys are same.
  3. You need to use every() inside findIndex() to check if all keys which needs to be matched have same value.
  4. If findIndex() returns -1 add the item to ac otherwise increase Amount of item at the index found

let array = [
    { CategoryId: 'Cat1', Amount: 15, Type: 'TypeA' },
    { CategoryId: 'Cat1', Amount: 30, Type: 'TypeA' },
    { CategoryId: 'Cat1', Amount: 20, Type: 'TypeB' },
    { CategoryId: 'Cat2', Amount: 10, Type: 'TypeA' },
    { CategoryId: 'Cat2', Amount: 5, Type: 'TypeB' }]
function addBy(arr,keys){
  return arr.reduce((ac,a) => {
    let ind = ac.findIndex(x => keys.every(k => x[k] === a[k]));
    ind === -1 ? ac.push(a) : ac[ind].Amount += a.Amount;
    return ac;
  },[])
}
console.log(addBy(array,["CategoryId","Type"]));
like image 152
Maheer Ali Avatar answered Nov 15 '22 01:11

Maheer Ali