Faysal Ahmed
Faysal Ahmed

Reputation: 1542

merge object & sum a single property javascript

i have an array like this

[
  {
    item_guid: "57e7a1cd6a3f3669dc03db58"
    quantity:3
  },
  {
    item_guid: "57e77b06e0566d496b51fed5"
    quantity:3
  },
  {
    item_guid: "57e7a1cd6a3f3669dc03db58"
    quantity:3
   },
  {
    item_guid: "57e77b06e0566d496b51fed5"
    quantity:3
  }
]

What i want from this to merge similar item_guid into one object and quantity get summed up like this

[
  {
    item_guid: "57e7a1cd6a3f3669dc03db58"
    quantity:6
   },
  {
    item_guid: "57e77b06e0566d496b51fed5"
    quantity:6
  }
]

I know this can be achieved some loop, instead I'm looking for solutions that uses lodash or EcmaScript2015 code to make our life easier

Upvotes: 9

Views: 7040

Answers (4)

Rajesh
Rajesh

Reputation: 24915

A simple approach:

Loop over data and create an object where key will be unique id and its value will be quantity. Then loop back over object's keys and create objects.

var data = [{ item_guid: "57e7a1cd6a3f3669dc03db58", quantity: 3 }, { item_guid: "57e77b06e0566d496b51fed5", quantity: 3 }, { item_guid: "57e7a1cd6a3f3669dc03db58", quantity: 3 }, { item_guid: "57e77b06e0566d496b51fed5", quantity: 3 }]

var r = {};
data.forEach(function(o){
  r[o.item_guid] = (r[o.item_guid] || 0) + o.quantity;
})

var result = Object.keys(r).map(function(k){
  return { item_guid: k, quantity: r[k] }
});
console.log(result)

Upvotes: 5

nikoshr
nikoshr

Reputation: 33334

You can

  • group your objects by item_guid
  • sum the objects in the resulting groups
  • transform these groups in the format you want

Something like this:

var result = _.chain(data)
    .groupBy('item_guid')
    .map(function(objects, guid) {
        return {
            item_guid: guid, 
            quantity: _.sumBy(objects, 'quantity')
        };
    })
    .value();

And a demo

var data = [
  {
    item_guid: "57e7a1cd6a3f3669dc03db58",
    quantity:3
  },
  {
    item_guid: "57e77b06e0566d496b51fed5",
    quantity:3
  },
  {
    item_guid: "57e7a1cd6a3f3669dc03db58",
    quantity:3
   },
  {
    item_guid: "57e77b06e0566d496b51fed5",
    quantity:3
  }
];


var result = _.chain(data)
    .groupBy('item_guid')
    .map(function(objects, guid) {
        return {
            item_guid: guid, 
            quantity: _.sumBy(objects, 'quantity')
        };
    })
    .value();
  
  console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.4/lodash.min.js"></script>

Upvotes: 1

chanoto89
chanoto89

Reputation: 241

var groupedItems = [];

var totalItems = [{item_guid: "57e7a1cd6a3f3669dc03db58", quantity:3},{item_guid: "57e77b06e0566d496b51fed5",quantity:3}, { item_guid: "57e7a1cd6a3f3669dc03db58", quantity:3 }, { item_guid: "57e77b06e0566d496b51fed5", quantity:3}];

totalItems.forEach((e) => {
  if (groupedItems.findIndex(x => x.item_guid === e.item_guid) < 0) {
    let totalQuantity = totalItems
                       .filter(x => x.item_guid === e.item_guid)
                       .map(x => x.quantity)
                       .reduce(function(a, b) { return a + b;});

    groupedItems.push({item_guid: e.item_guid, quantity: totalQuantity})
  }
})

console.log(groupedItems);

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386520

A solution in plain Javascript with a hash table for item_guid.

var data = [{ item_guid: "57e7a1cd6a3f3669dc03db58", quantity: 3 }, { item_guid: "57e77b06e0566d496b51fed5", quantity: 3 }, { item_guid: "57e7a1cd6a3f3669dc03db58", quantity: 3 }, { item_guid: "57e77b06e0566d496b51fed5", quantity: 3 }],
    grouped = data.reduce(function (hash) {
        return function (r, a) {
            (hash[a.item_guid] = hash[a.item_guid] || r[r.push({ item_guid: a.item_guid, quantity: 0 }) - 1]).quantity += a.quantity;
            return r;
        };
    }(Object.create(null)), []);

console.log(grouped);

ES6

var data = [{ item_guid: "57e7a1cd6a3f3669dc03db58", quantity: 3 }, { item_guid: "57e77b06e0566d496b51fed5", quantity: 3 }, { item_guid: "57e7a1cd6a3f3669dc03db58", quantity: 3 }, { item_guid: "57e77b06e0566d496b51fed5", quantity: 3 }],
    grouped = data.reduce((map => (r, a) => {
        map.set(a.item_guid, map.get(a.item_guid) || r[r.push({ item_guid: a.item_guid, quantity: 0 }) - 1]);
        map.get(a.item_guid).quantity += a.quantity;
        return r;
    })(new Map), []);

console.log(grouped);

Upvotes: 4

Related Questions