Reputation: 327
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);
}
Upvotes: 0
Views: 102
Reputation: 28404
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);
Upvotes: 1
Reputation: 29071
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
}, [] )
Upvotes: 0