如何使用reduce重组产品与订单关联数据?
如何用reduce将产品与关联订单合并?
原始数据结构
从API获取的数据结构如下:
interface ProductModel { prod_id: string, brand: string, // 其他产品字段... } interface OrderModel { order_id: string, prod_id: string, // 其他订单字段... } const data = { products: ProductModel[], orders: OrderModel[] }
需求
需要将数据重组,把每个产品对应的订单与产品信息合并,最终结构如下:
type MergedProduct = { prod_id: string, brand: string, // 其他产品字段... orders: OrderModel[] }
用reduce实现的方案(附原理讲解)
先搞懂reduce的核心逻辑
reduce 是数组的迭代方法,核心作用是把数组的每一项逐步整合到一个累加器中,最终输出累加器的最终状态。它可以把数组“压缩”成任意类型的值(对象、数组、数字等)。
基本语法:
数组.reduce((累加器, 当前项) => { // 对累加器和当前项做处理,返回更新后的累加器 }, 初始累加器值)
高效实现:先分组订单再合并产品
步骤1:将订单按prod_id分组
先把订单数组转成以prod_id为键、对应订单数组为值的对象,这样后续匹配产品订单时无需重复遍历整个订单数组,效率更高:
// 用reduce构建订单分组对象 const ordersByProdId = data.orders.reduce((acc, order) => { // 如果当前prod_id未在累加器中,初始化空数组 if (!acc[order.prod_id]) { acc[order.prod_id] = []; } // 将当前订单加入对应prod_id的数组 acc[order.prod_id].push(order); // 返回更新后的累加器,供下一次迭代使用 return acc; }, {} as Record<string, OrderModel[]>);
步骤2:合并产品与对应订单
再用reduce遍历产品数组,为每个产品添加对应的订单数组:
// 用reduce生成最终的合并数据 const mergedProducts = data.products.reduce((acc, product) => { // 合并产品信息与对应订单(无订单则设为空数组) const mergedItem = { ...product, orders: ordersByProdId[product.prod_id] || [] }; // 将合并后的对象加入累加器数组 acc.push(mergedItem); // 返回更新后的累加器 return acc; }, [] as MergedProduct[]);
简化版:一步到位的reduce实现
如果追求代码紧凑,也可以跳过分组步骤,直接在reduce中匹配订单(注意:此方法每个产品都会遍历一次订单数组,数据量大时效率较低):
const mergedProducts = data.products.reduce((acc, product) => { // 筛选当前产品对应的所有订单 const productOrders = data.orders.filter(order => order.prod_id === product.prod_id); // 合并产品与订单后加入累加器 acc.push({ ...product, orders: productOrders }); return acc; }, [] as MergedProduct[]);
拆解reduce的执行过程(以订单分组为例)
拿第一个分组的reduce代码逐行看:
- 初始累加器是
{} as Record<string, OrderModel[]>,即一个空对象,用来存储每个prod_id对应的订单数组。 - 遍历每一个订单:
- 检查累加器中是否存在当前订单的
prod_id键,不存在则初始化空数组。 - 将当前订单推入对应prod_id的数组。
- 返回更新后的累加器,作为下一次迭代的初始值。
- 检查累加器中是否存在当前订单的
- 遍历完所有订单后,累加器就变成了一个键为prod_id、值为对应订单数组的对象,后续直接通过prod_id就能快速获取订单。
内容的提问来源于stack exchange,提问作者Emili Bellot Pulido
相关产品推荐
相关产品推荐

