JavaScript遍历嵌套对象数组并合并数值的实现方案
合并嵌套对象数组中的成分数据
现有一个包含嵌套属性的对象数组,需遍历该数组并合并其中的成分数据,假设所有物品/成分的单位一致(后续再处理单位转换)。
原始代码
var items = [{ name: "flat bread", price: "5", components: [ { qty: 120, unit: "g", ingredient: { name: "flour", price: 1, perAmount: 1, unit: "kg" } }, { qty: 250, unit: "mL", ingredient: { name: "milk", price: 4, perAmount: 3, unit: "litre" } }, { qty: 1.5, unit: "g", ingredient: { name: "salt", price: 1.2, perAmount: 1, unit: "kg" } }, { qty: 28.35, unit: "g", ingredient: { name: "butter", price: "6", perAmount: 500, unit: "g" } } ] }, { name: "pancake", price: "15", components: [ { qty: 120, unit: "g", ingredient: { name: "flour", price: 1, perAmount: 1, unit: "kg" } }, { qty: 250, unit: "mL", ingredient: { name: "milk", price: 4, perAmount: 3, unit: "litre" } }, { qty: 2, unit: "each", ingredient: { name: "egg", price: 5, perAmount: 12, unit: "each" } }, { qty: 12.5, unit: "g", ingredient: { name: "sugar", price: 2.20, perAmount: 2, unit: "kg" } } ] }, { name: "crepe", price: "10", components: [ { qty: 120, unit: "g", ingredient: { name: "flour", price: 1, perAmount: 1, unit: "kg" } }, { qty: 250, unit: "mL", ingredient: { name: "milk", price: 4, perAmount: 3, unit: "litre" } }, { qty: 2, unit: "each", ingredient: { name: "egg", price: 5, perAmount: 12, unit: "each" } }, { qty: 28.35, unit: "g", ingredient: { name: "butter", price: "6", perAmount: 500, unit: "g" } } ] } ];
期望结果
- 360g flour
- 750ml milk
- 1.5g salt
- 4 eggs
- 12.5g sugar
- 56.7g butter
解决方案
核心思路是先提取所有成分并合并为一维数组,再以食材名称为键累加数量,最后格式化输出:
// 1. 提取所有物品的components并合并成一维数组 const allComponents = items.flatMap(item => item.components); // 2. 用对象累加相同食材的数量 const consolidated = {}; allComponents.forEach(comp => { const ingredientName = comp.ingredient.name; if (consolidated[ingredientName]) { consolidated[ingredientName].qty += comp.qty; } else { consolidated[ingredientName] = { qty: comp.qty, unit: comp.unit }; } }); // 3. 格式化为期望的字符串列表 const finalResult = Object.entries(consolidated).map(([name, data]) => { const formattedQty = Number(data.qty.toFixed(2)); // 针对"each"单位做特殊格式处理 if (data.unit === 'each') { return `${formattedQty} ${name}s`; } return `${formattedQty}${data.unit.toLowerCase()} ${name}`; }); // 打印结果 console.log(finalResult);
代码说明
flatMap合并数组:将每个物品的components数组展开,得到所有成分的一维数组,简化后续遍历逻辑。- 对象累加数量:以食材名称为唯一键,遍历过程中相同食材直接累加数量,不同食材则初始化键值对,高效完成合并。
- 格式化输出:根据单位调整显示格式,比如
each单位的食材转为数量 + 复数食材名,其他单位直接拼接数量、单位与食材名,匹配期望结果。
内容的提问来源于stack exchange,提问作者Joseph P
相关产品推荐
相关产品推荐

