Reputation: 163
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 ?
Upvotes: 0
Views: 116
Reputation: 4175
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.
Upvotes: 1
Reputation: 22574
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>
Upvotes: 1
Reputation: 2099
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);
Upvotes: 1
Reputation: 386883
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; }
Upvotes: 1
Reputation: 2390
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
Upvotes: 1