JavaScript reduce 小練習
題目說明
你收到一筆餐廳的點餐紀錄資料,格式如下:
const orders = [
{ item: "Burger", quantity: 2 },
{ item: "Fries", quantity: 3 },
{ item: "Burger", quantity: 1 },
{ item: "Soda", quantity: 5 },
{ item: "Fries", quantity: 1 },
];
請撰寫一個函式 summarizeOrders(orders)
,輸出每種品項的總數量,格式如下:
{
Burger: 3,
Fries: 4,
Soda: 5
}
✅ 解法一:使用 forEach
const summarizeOrders = (orders) => {
const result = {};
orders.forEach(order => {
if (result[order.item]) {
result[order.item] += order.quantity;
} else {
result[order.item] = order.quantity;
}
});
return result;
};
console.log(summarizeOrders(orders));
// ➜ { Burger: 3, Fries: 4, Soda: 5 }
解法說明:
- 建立空物件
result
來存放結果 - 使用
forEach
遍歷每筆訂單 - 檢查該品項是否已存在於結果物件中
- 如果存在就累加數量,不存在就設定初始數量
- 回傳結果物件
✅ 解法二:使用 reduce
const summarizeOrders = (orders) => {
return orders.reduce((acc, curr) => {
if (acc[curr.item]) {
acc[curr.item] += curr.quantity;
} else {
acc[curr.item] = curr.quantity;
}
return acc;
}, {});
};
console.log(summarizeOrders(orders));
// ➜ { Burger: 3, Fries: 4, Soda: 5 }
解法說明:
- 使用
reduce
將陣列歸約成一個物件 acc
(累加器)初始值為空物件{}
- 每次迭代檢查品項是否存在並累加數量
- 必須回傳
acc
給下次迭代使用
✅ 精簡寫法(推薦)
const summarizeOrders = (orders) =>
orders.reduce((acc, { item, quantity }) => {
acc[item] = (acc[item] || 0) + quantity;
return acc;
}, {});
console.log(summarizeOrders(orders));
// ➜ { Burger: 3, Fries: 4, Soda: 5 }
精簡技巧說明:
- 解構賦值:
{ item, quantity }
直接取出物件屬性 - 短路運算:
(acc[item] || 0)
如果acc[item]
不存在則使用 0 - 一行解決:避免 if/else 判斷,代碼更簡潔
🔍 重要概念解析
短路運算技巧
// 這兩種寫法效果相同:
// 傳統寫法
if (acc[item]) {
acc[item] += quantity;
} else {
acc[item] = quantity;
}
// 短路寫法
acc[item] = (acc[item] || 0) + quantity;
運作原理:
- 如果
acc[item]
存在且不為 falsy,使用原值 - 如果
acc[item]
不存在或為 falsy,使用 0
🎯 延伸練習
練習 1:加入品項價格統計
const ordersWithPrice = [
{ item: "Burger", quantity: 2, price: 120 },
{ item: "Fries", quantity: 3, price: 60 },
{ item: "Burger", quantity: 1, price: 120 },
];
// 期望輸出:
// {
// Burger: { quantity: 3, totalPrice: 360 },
// Fries: { quantity: 3, totalPrice: 180 }
// }
解答:
const summarizeOrdersWithPrice = (orders) =>
orders.reduce((acc, { item, quantity, price }) => {
if (!acc[item]) {
acc[item] = { quantity: 0, totalPrice: 0 };
}
acc[item].quantity += quantity;
acc[item].totalPrice += quantity * price;
return acc;
}, {});
練習 2:找出最受歡迎的品項
const findMostPopular = (orders) => {
const summary = summarizeOrders(orders);
return Object.keys(summary).reduce((most, item) =>
summary[item] > summary[most] ? item : most
);
};
console.log(findMostPopular(orders)); // "Soda"