Предположим, что ваши отдельные продуктовые зоны всегда имеют длину 1.
const sample = [
{
"commissioningDate": "2019-09-27",
"_product": {
"_id": "aaa",
"name": "Installation"
},
"zones": [
{
"_zone": {
"_id": "KK",
"name": "Zone kk"
},
"category": "category1",
"zone_quantity": 6
}
],
"product_quantity": 3
},
{
"commissioningDate": "2019-09-27",
"_product": {
"_id": "aaa",
"name": "Installation"
},
"zones": [
{
"_zone": {
"_id": "KK",
"name": "Zone kk"
},
"category": "category2",
"zone_quantity": 3
}
],
"product_quantity": 2
},
{
"commissioningDate": "2019-09-27",
"_product": {
"_id": "aaa",
"name": "Installation"
},
"zones": [
{
"_zone": {
"_id": "KK",
"name": "Zone kk"
},
"category": "category2",
"zone_quantity": 4
}
],
"product_quantity": 5
},
{
"commissioningDate": "2019-09-27",
"_product": {
"_id": "aaa",
"name": "Installation"
},
"zones": [
{
"_zone": {
"_id": "CC",
"name": "Zone cc"
},
"category": "category2",
"zone_quantity": 6
}
],
"product_quantity": 1
},
{
"commissioningDate": "2019-09-27",
"_product": {
"_id": "bbbb",
"name": "Installation"
},
"zones": [
{
"_zone": {
"_id": "CC",
"name": "Zone cc"
},
"category": "category2",
"zone_quantity": 8
}
],
"product_quantity": 2
},
{
"commissioningDate": "2019-09-26",
"_product": {
"_id": "bbbb",
"name": "Installation"
},
"zones": [
{
"_zone": {
"_id": "CC",
"name": "Zone cc"
},
"category": "category2",
"zone_quantity": 8
}
],
"product_quantity": 2
}
]
//reduce initialze value is an empty object
const res = sample.reduce((group, item) => {
//for each item, generate a key k by combining item commissioningDate and item _product._id seperated //by a comma
const k = `${item.commissioningDate},${item._product._id}`;
//check if this key k exists in our object group(which is an empty object when we check the first //item)
//if it is not in the object, we save the key k and its value which is current item into the object //group
if(!group[k]) group[k] = Object.assign({}, item);
//if it is in the object already
else{
//we sum up current item quantity to the group of this item
group[k].product_quantity+=item.product_quantity;
//find index of zone in current group zones has the same zone id and category as item's
for(const itemZone of item.zones){
const zoneIdx = group[k].zones.findIndex(zone => zone._zone._id === itemZone._zone._id && zone.category === itemZone.category)
//index is -1, it's not in group zones, we push the zone to group zones array
if(zoneIdx === -1){
group[k].zones.push(itemZone)
}
//in group zones, we sum up zone_quantity
else{
group[k].zones[zoneIdx].zone_quantity += itemZone.zone_quantity
}
}
}
//update current group
return group
}, {})
//recall keys are our custom identifier for different groups of items, values are actually groups of //items, so we only need to get values from group object
console.log(Object.values(res))