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 其中keyproductNamestorage的组合,值为对应的分组对象
  • 在每次迭代中,使用当前密钥,获取对(如果存在)并解构 stockInstockOut。根据当前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);