Taha Farooqui
Taha Farooqui

Reputation: 747

JavaScript merge objects with same key and sum their values

The code is working fine as expected but the name parameter is missing in response.

var objArr= [{'location_id':1,'quantity':20,'name':'AB'},{'location_id':1,'quantity':20,'name':'AB'},{'location_id':3,'quantity':20,'name':'cd'}]

// first, convert data into a Map with reduce
let counts = objArr.reduce((prev, curr) => {
  let count = prev.get(curr.location_id) || 0;
  prev.set(curr.location_id, (curr.quantity + count),curr.name);
  return prev;
}, new Map());

// then, map your counts object back to an array
let reducedObjArr = [...counts].map(([location_id, quantity,name]) => {
  return {location_id, quantity,name}
})


console.log (reducedObjArr);

Expected Response:

[
{"location_id":1,"quantity":40, "name":'AB'},
{"location_id":3,"quantity":20, "name":'cd'}
]

Upvotes: 4

Views: 1658

Answers (2)

Mister Jojo
Mister Jojo

Reputation: 22320

the simplest way:

const objArr = 
    [ { location_id: 1, quantity: 20, name: 'AB' } 
    , { location_id: 1, quantity: 20, name: 'AB' } 
    , { location_id: 3, quantity: 20, name: 'cd' } 
    ] 
     
const sum = objArr.reduce((a,c)=>{
  let x = a.find(e=>e.location_id===c.location_id)
  if(!x) a.push(Object.assign({},c))
  else  x.quantity += c.quantity
  return a
},[])

console.log(sum)
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 7

customcommander
customcommander

Reputation: 18901

You can solve this problem by solving smaller problems and designing reusable functions.

First group related objects

From:

[ { location_id:1, quantity:20, name:'AB' }
, { location_id:1, quantity:20, name:'AB' }
, { location_id:3, quantity:20, name:'cd' }
]

To:

{ AB: [ { location_id:1, quantity:20, name:'AB' }
      , { location_id:1, quantity:20, name:'AB' }
      ]
, cd: [ { location_id:3, quantity:20, name:'cd' }
      ]
}

Then merge each set

From:

[ [ { location_id:1, quantity:20, name:'AB' }
  , { location_id:1, quantity:20, name:'AB' }
  ]
, [ { location_id:3, quantity:20, name:'cd' }
  ]
]

To:

[ { location_id:1, quantity:40, name:'AB' }
, { location_id:3, quantity:20, name:'cd' }
]

const group_name =
  group_by('name');

const sum_quantity =
  merge_key_with('quantity', (a, b) => a + b);
  
const answer =
  Object.values(group_name(data)).map(sum_quantity);
  
console.log(answer);
<script>
const data =
  [ { location_id:1, quantity:20, name:'AB' }
  , { location_id:1, quantity:20, name:'AB' }
  , { location_id:3, quantity:20, name:'cd' }
  ];

const group_by =
  k => xs =>
    xs.reduce
      ( (acc, x) =>
          ( acc[x[k]]
              ? acc[x[k]].push(x)
              : acc[x[k]] = [x]
          , acc
          )
      , {}
      );

const merge_key_with =
  (k, fn) => xs =>
    xs.slice(1).reduce
      ( (acc, o) =>
          ( acc[k] = fn(acc[k], o[k])
          , acc
          )
      , {...xs[0]}
      );
</script>

Upvotes: 1

Related Questions