This is my object
let products = [
{ "productName": "A", "storage": "Lot 1", "quantity": 1000, "status": "stockIn" },
{ "productName": "A", "storage": "Lot 1", "quantity": 100, "status": "stockIn" },
{ "productName": "A", "storage": "Lot 1", "quantity": 500, "status": "stockOut" },
{ "productName": "A", "storage": "Lot 2", "quantity": 500, "status": "stockIn" }
]
This is what I am trying to achieve
let result = [
{ "productName": "A", "storage": "Lot 1", "stockIn": 1100, "stockOut": 500, "available":600 },
{ "productName": "A", "storage": "Lot 2", "stockIn": 500, "stockOut": 0, "available":500 }
]
Please kindly provide an idea on how to achieve this without redundant codes. Thanks
var storage = new Set(products.map(item => item.storage));
storage.forEach(lot => {
var stockIn = products.filter(item => item.storage === storage && item.status == 'stockIn')
.map(({ storage, quantity }) => ({ storage, quantity }));
var stockInSum = stockIn.reduce((prev, curr, index) => prev + curr.quantity, 0);
var stockOut = products.filter(item => item.storage === storage && item.status == 'stockOut')
.map(({ storage, quantity }) => ({ storage, quantity }))
var stockOutSum = stockOut.reduce((prev, curr, index) => prev + curr.quantity, 0);
}
Array#reduce, iterate over the array while updating a Map where the key is the combination of productName and storage, and the value is the corresponding grouped objectstockIn and stockOut. According to the current status, update one of the latter values and compute available. Finally, using Map#set, create/update the pair.Map#values, get the list of grouped objectsconst products = [
{ productName: "A", storage: "Lot 1", quantity: 1000, status: "stockIn" },
{ productName: "A", storage: "Lot 1", quantity: 100, status: "stockIn" },
{ productName: "A", storage: "Lot 1", quantity: 500, status: "stockOut" },
{ productName: "A", storage: "Lot 2", quantity: 500, status: "stockIn" }
];
const result = [...
products.reduce((map, { productName, storage, quantity, status }) => {
const key = `${productName}-${storage}`;
let { stockIn = 0, stockOut = 0 } = map.get(key) ?? {};
if(status === 'stockIn') stockIn += quantity;
else stockOut += quantity;
const available = stockIn - stockOut;
map.set(key, { productName, storage, stockIn, stockOut, available });
return map;
}, new Map)
.values()
];
console.log(result);
Here is the general pattern. I will leave it to you to figure out the other fields.
const reduced = products.reduce( (a,v) => {
const found = a.find(it=>it.lot === v.lot && it.productName === v.productName)
if (found) {
a.quantity += v.quantity
// aggregate your other fields here.
}
else {
a.push(v)
}
return a
}, [] )