You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript合并两个数组 为订单数据添加orderHasAlcohol字段

问题需求

现有两组数据:订单数组ordersData、拣货单数据pickingOrder,二者通过orderId(对应订单数据里的id字段)关联匹配。拣货单是嵌套结构,内部存储了orderHasAlcohol字段,需要生成新数组,把拣货单中对应订单的orderHasAlcohol字段合并到原订单数据的对应项中。优先支持Ramda函数式实现,原生JS实现也可接受。


原始数据

订单数组 ordersData

const ordersData = [
  {
    additionalInfo: null,
    comment: null,
    deliveryDate: "2022-07-14",
    deliveryMethod: "PICKUP",
    deliveryTime: "10-12",
    discountCode: null,
    id: "1234", // orderId
    orderStatus: "NEW",
    paymentMethod: "ON_DELIVERY",
    paymentStatus: "UNAVAILABLE",
    storeId: "12345",
  },
  {
    additionalInfo: null,
    comment: null,
    deliveryDate: "2022-07-23",
    deliveryMethod: "PICKUP",
    deliveryTime: "10-12",
    discountCode: null,
    id: "123", // orderId
    orderStatus: "NEW",
    paymentMethod: "ON_DELIVERY",
    paymentStatus: "UNAVAILABLE",
    storeId: "12345",
  },
  {
    additionalInfo: null,
    comment: null,
    deliveryDate: "2022-07-23",
    deliveryMethod: "PICKUP",
    deliveryTime: "10-12",
    discountCode: null,
    id: "198", // orderId
    orderStatus: "NEW",
    paymentMethod: "ON_DELIVERY",
    paymentStatus: "UNAVAILABLE",
    storeId: "12345",
  },

  {
    additionalInfo: null,
    comment: null,
    deliveryDate: "2022-07-23",
    deliveryMethod: "PICKUP",
    deliveryTime: "10-12",
    discountCode: null,
    id: "125", // orderId
    orderStatus: "NEW",
    paymentMethod: "ON_DELIVERY",
    paymentStatus: "UNAVAILABLE",
    storeId: "12345",
  },
];

拣货单数据 pickingOrder

const pickingOrder = {
  ordersPickedAndDone: {
    orderCount: 0,
    rows: [],
  },
  ordersPickedAndPaid: {
    orderCount: 0,
    rows: [],
  },
  ordersPickedCanStart: {
    orderCount: 2,
    rows: [
      {
        orderHasAlcohol: false,
        orderId: "123",
      },
      {
        orderHasAlcohol: true,
        orderId: "198",
      },
    ],
  },
  ordersPickingProgress: {
    orderCount: 2,
    rows: [
      {
        pickingRun: 1,
        partitions: [
          {
            orderHasAlcohol: false,
            orderId: "125",
          },
          {
            orderHasAlcohol: true,
            orderId: "1234",
          },
        ],
      },
    ],
  },
};

预期输出

const expectedArrays = [
  {
    additionalInfo: null,
    comment: null,
    deliveryDate: "2022-07-14",
    deliveryMethod: "PICKUP",
    deliveryTime: "10-12",
    discountCode: null,
    id: "1234", // orderId
    orderStatus: "NEW",
    paymentMethod: "ON_DELIVERY",
    paymentStatus: "UNAVAILABLE",
    storeId: "12345",
    orderHasAlcohol: true,
  },

  {
    additionalInfo: null,
    comment: null,
    deliveryDate: "2022-07-23",
    deliveryMethod: "PICKUP",
    deliveryTime: "10-12",
    discountCode: null,
    id: "123", // orderId
    orderStatus: "NEW",
    paymentMethod: "ON_DELIVERY",
    paymentStatus: "UNAVAILABLE",
    storeId: "12345",
    orderHasAlcohol: false,
  },
  {
    additionalInfo: null,
    comment: null,
    deliveryDate: "2022-07-23",
    deliveryMethod: "PICKUP",
    deliveryTime: "10-12",
    discountCode: null,
    id: "198", // orderId
    orderStatus: "NEW",
    paymentMethod: "ON_DELIVERY",
    paymentStatus: "UNAVAILABLE",
    storeId: "12345",
    orderHasAlcohol: true,
  },

  {
    additionalInfo: null,
    comment: null,
    deliveryDate: "2022-07-23",
    deliveryMethod: "PICKUP",
    deliveryTime: "10-12",
    discountCode: null,
    id: "125", // orderId
    orderStatus: "NEW",
    paymentMethod: "ON_DELIVERY",
    paymentStatus: "UNAVAILABLE",
    storeId: "12345",
    orderHasAlcohol: false,
  },
];

console.log({expectedArrays});

实现方案

核心逻辑分两步:

  • 先遍历嵌套的拣货单结构,把所有orderId和对应的orderHasAlcohol提取成扁平映射表,避免重复遍历深层结构,提升匹配效率
  • 遍历原订单数组,从映射表中取出对应字段合并到订单对象中,全程不修改原始数据

方案1:原生JS实现

// 1. 构建orderId -> orderHasAlcohol的映射
const alcoholMap = {};

// 提取普通rows层级的订单
Object.values(pickingOrder).forEach(statusGroup => {
  statusGroup.rows?.forEach(row => {
    if (row.orderId) {
      alcoholMap[row.orderId] = row.orderHasAlcohol;
    }
    // 提取partitions嵌套层级的订单
    row.partitions?.forEach(partition => {
      if (partition.orderId) {
        alcoholMap[partition.orderId] = partition.orderHasAlcohol;
      }
    })
  })
})

// 2. 合并字段到原订单
const mergedOrders = ordersData.map(order => ({
  ...order,
  orderHasAlcohol: alcoholMap[order.id]
}))

方案2:Ramda函数式实现

遵循Ramda无点风格编写,逻辑和原生实现一致,扩展性更强:

import * as R from 'ramda';

// 递归提取单条拣货记录(兼容普通row和多层嵌套结构)
const extractOrderEntry = R.cond([
  [R.has('orderId'), item => R.objOf(item.orderId, item.orderHasAlcohol)],
  [R.has('partitions'), R.pipe(
    R.prop('partitions'),
    R.map(extractOrderEntry),
    R.mergeAll
  )],
  [R.T, R.always({})]
])

// 构建alcohol映射表
const buildAlcoholMap = R.pipe(
  R.values,
  R.map(R.prop('rows')),
  R.flatten,
  R.map(extractOrderEntry),
  R.mergeAll
)

// 合并订单
const mergeOrders = R.converge(
  R.mapWith((order, alcoholMap) => R.assoc('orderHasAlcohol', alcoholMap[order.id], order)),
  [R.identity, buildAlcoholMap]
)

// 调用获取结果
const mergedOrders = mergeOrders(ordersData, pickingOrder)

两种方案输出结果和预期完全一致,如果后续拣货单新增其他嵌套层级,只需要在提取映射的逻辑里补充对应层级的遍历规则即可。


内容的提问来源于stack exchange,提问作者user12494839

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 12:10:34