JavaScript 减少对象
JavaScript Reduce with Objects
这是我的对象
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" }
]
这就是我想要实现的目标
let result = [
{ "productName": "A", "storage": "Lot 1", "stockIn": 1100, "stockOut": 500, "available":600 },
{ "productName": "A", "storage": "Lot 2", "stockIn": 500, "stockOut": 0, "available":500 }
]
请提供有关如何在没有冗余代码的情况下实现此目的的想法。谢谢
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);
}
这是一般模式。我将留给您找出其他字段。
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
}, [] )
- Using
Array#reduce
, iterate over the array while updating a Map
其中key
是productName
和storage
的组合,值为对应的分组对象
- 在每次迭代中,使用当前密钥,获取对(如果存在)并解构
stockIn
和 stockOut
。根据当前status
,更新后面的一个值并计算available
。最后,使用Map#set
、create/update对。
- 使用
Map#values
,获取分组对象列表
const 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);
这是我的对象
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" }
]
这就是我想要实现的目标
let result = [
{ "productName": "A", "storage": "Lot 1", "stockIn": 1100, "stockOut": 500, "available":600 },
{ "productName": "A", "storage": "Lot 2", "stockIn": 500, "stockOut": 0, "available":500 }
]
请提供有关如何在没有冗余代码的情况下实现此目的的想法。谢谢
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);
}
这是一般模式。我将留给您找出其他字段。
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
}, [] )
- Using
Array#reduce
, iterate over the array while updating aMap
其中key
是productName
和storage
的组合,值为对应的分组对象 - 在每次迭代中,使用当前密钥,获取对(如果存在)并解构
stockIn
和stockOut
。根据当前status
,更新后面的一个值并计算available
。最后,使用Map#set
、create/update对。 - 使用
Map#values
,获取分组对象列表
const 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);