0

Hi guys i've question about how to group by key id value and do sum on ( key harga value and key qty value) below are the array of objects:

order: [
  {
    id: 4,
    idkatg: 2,
    kategori: 'minuman',
    nmprod: 'es mambo',
    harga: 8000,
    qty: 1
  },
  {
    id: 4,
    idkatg: 2,
    kategori: 'minuman',
    nmprod: 'es mambo',
    harga: 8000,
    qty: 1
  }
]

what i wan't to achieve is like this :

order:[
   {
     id: 4,
     idkatg: 2,
     kategori: 'minuman',
     nmprod: 'es mambo',
     harga: 14000,
     qty: 2
   }
]

is there any solution using lodash maybe ?

4
  • 6
    8000 + 8000 = 14000? btw, what have you tried? Commented Sep 24, 2018 at 8:33
  • 2
    Please show us what have you tried. Commented Sep 24, 2018 at 8:34
  • @NinaScholz hahaha Commented Sep 24, 2018 at 8:34
  • sorry guys but i have to wrap my head first with all these answer. i'll get back then Commented Sep 24, 2018 at 9:05

5 Answers 5

1

You could reduce the object and find the object with the same id, then update. Otherwise push the actual object to the result set.

If needed, you could take a sloppy copy with

r.push(Object.assign({}, o));

var order = [{ id: 4, idkatg: 2, kategori: 'minuman', nmprod: 'es mambo', harga: 8000, qty: 1 }, { id: 4, idkatg: 2, kategori: 'minuman', nmprod: 'es mambo', harga: 8000, qty: 1 }];

order = order.reduce((r, o) => {
   var temp = r.find(({ id }) => id === o.id);
   if (temp) {
       ['harga', 'qty'].forEach(k => temp[k] += o[k]);
   } else {
       r.push(o);
   }
   return r;
}, []);

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

Sign up to request clarification or add additional context in comments.

1 Comment

I think your answer is much simple and elegant. Thanks
1

Try this:

const order = [
  {
    id: 4,
    idkatg: 2,
    kategori: 'minuman',
    nmprod: 'es mambo',
    harga: 8000,
    qty: 1
  },
  {
    id: 4,
    idkatg: 2,
    kategori: 'minuman',
    nmprod: 'es mambo',
    harga: 8000,
    qty: 1
  }
];

const newOrder = [];

for (const index in order) {
  const item = order[index];
  const itemInNewOrder = newOrder.filter(i => i.id === item.id)[0];

  if (itemInNewOrder) {
    itemInNewOrder.harga += item.harga;
  } else {
    newOrder.push(item);
  }
}

console.log(newOrder);

This question is similar to: Merge objects with the same id but sum values of the objects

Comments

1

You can use 2 pure for loops to set:

var order = [
  {
    id: 4,
    idkatg: 2,
    kategori: 'minuman',
    nmprod: 'es mambo',
    harga: 8000,
    qty: 1
  },
  {
    id: 4,
    idkatg: 2,
    kategori: 'minuman',
    nmprod: 'es mambo',
    harga: 8000,
    qty: 1
  },
  {
    id: 5,
    idkatg: 3,
    kategori: '5 minuman',
    nmprod: '5 es mambo',
    harga: 5000,
    qty: 3
  },
  {
    id: 5,
    idkatg: 3,
    kategori: '5 minuman',
    nmprod: '5 es mambo',
    harga: 4000,
    qty: 2
  },
  {
    id: 6,
    idkatg: 4,
    kategori: '6 minuman',
    nmprod: '6 es mambo',
    harga: 6000,
    qty: 2
  }
];

var result = [];
result.push(order[0]);
for (var i=1; i<order.length; i++){
  //compare object order[i] with order[0] ... order[n]
  var flagExist = false;
  for (var j=0; j<i; j++){
    if(order[j].id === order[i].id){
      flagExist = true;
      //set for object old, with new qty and harga
      order[j].qty = order[i].qty + order[j].qty;
      order[j].harga = order[i].harga + order[j].harga;
      break;
    }
  }
  if (flagExist == false)
    result.push(order[i]);
}
console.log(result);

Comments

1

You can use groupBy based on the id key and then using map reduce using sumBy & fromPairs operation.

let order = [ { id: 4, idkatg: 2, kategori: 'minuman', nmprod: 'es mambo', harga: 8000, qty: 1 }, { id: 4, idkatg: 2, kategori: 'minuman', nmprod: 'es mambo', harga: 8000, qty: 1 } ],
    result = _(order).groupBy('id').map((o,k) =>
      ({...o[0], ..._.fromPairs(_(['qty','harga']).map(k => [k,_.sumBy(o,k)]).value())})).value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

Comments

1

Since you have tagged lodash this is as simple as (cleaner) this:

_(order).groupBy('id').map(a=>({...a[0], harga: _.sumBy(a, 'harga'), qty: _.sumBy(a, 'qty')})).value()

You can use reduce instead of 2 sumBy if you want to do the sum in a single iteration (however using lodash you are actually not looking for faster solution with less iterations anyway

let order = [
  {
    id: 4,
    idkatg: 2,
    kategori: 'minuman',
    nmprod: 'es mambo',
    harga: 8000,
    qty: 1
  },
  {
    id: 3,
    idkatg: 2,
    kategori: 'minuman',
    nmprod: 'es mambo',
    harga: 2000,
    qty: 1
  },
  {
    id: 4,
    idkatg: 2,
    kategori: 'minuman',
    nmprod: 'es mambo',
    harga: 8000,
    qty: 1
  },
  {
    id: 5,
    idkatg: 2,
    kategori: 'minuman',
    nmprod: 'es mambo',
    harga: 6000,
    qty: 1
  },
  {
    id: 5,
    idkatg: 2,
    kategori: 'minuman',
    nmprod: 'es mambo',
    harga: 9000,
    qty: 1
  }
];

let res =_(order).groupBy('id').map(a=>({...a[0], harga: _.sumBy(a, 'harga'), qty: _.sumBy(a, 'qty')})).value()

console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
https://stackoverflow.com/questions/52475365/group-array-of-objects/52475751#

There are Vanilla JS solution (and faster) for every lodash solution. But that's completely depend on you what you want, you are already using lodash or not. performance is really matter or cleanest code and maintainability and handling all the corner cases and some other factors.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.