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

如何对JS嵌套数组中同symbol的fulfilledQty求和并转目标数组?

问题

我有一个JavaScript数组,其中包含嵌套的对象数组。现在我想对拥有相同symbol键的对象的fulfilledQty字段进行求和,该如何实现?

现有数组

let orders = [
    {
        "_id": "6c18cea3-7d37-4f85-b369-abf03e7ff873",
        "subOrders": [
            {
                "symbol": "SUZ",
                "fulfilledQty": "49.333991119"
            },
            {
                "symbol": "FSLR",
                "fulfilledQty": "2.895864705"
            }
        ]
    },
    {
        "_id": "acf75fcb-496a-4825-b7bc-cef60556fe49",
        "subOrders": [
            {
                "symbol": "FSLR",
                "fulfilledQty": "1"
            },
            {
                "symbol": "SUZ",
                "fulfilledQty": "1"
            }
        ]
    },
    {
        "_id": "e32041a1-17f0-44c4-9fc4-4619e0507392",
        "subOrders": [
            {
                "symbol": "SUZ",
                "fulfilledQty": "8.751458576"
            },
            {
                "symbol": "FSLR",
                "fulfilledQty": "0.587774294"
            }
        ]
    }
]

期望结果

[
    {
        "symbol": "FSLR",
        "fulfilledQty": "4.483638999"
    },
    {
        "symbol": "SUZ",
        "fulfilledQty": "59.085449695"
    }
]

已尝试的代码

我已经写出了能实现功能的代码,但需要多次循环,想找更简洁的方式:

let totalOrder = {};
for(let order of orders){
    for(subOrder of order.subOrders){
        totalOrder[subOrder.symbol] = totalOrder[subOrder.symbol] ? 
            parseFloat(totalOrder[subOrder.symbol]) + 
            parseFloat(subOrder.fulfilledQty) : 
            parseFloat(subOrder.fulfilledQty);
    }
}

这段代码生成了如下对象,之后我会将其转换为数组:

{SUZ: 59.085449695, FSLR: 4.483638999} 

简洁实现方案

可以结合Array.prototype.flatMap()和Array.prototype.reduce()来简化代码,用链式调用完成所有逻辑,这里提供两种高效写法:

写法一:直接生成目标数组格式

const result = orders
  .flatMap(order => order.subOrders) // 扁平化所有subOrders为一维数组
  .reduce((acc, curr) => {
    const targetItem = acc.find(item => item.symbol === curr.symbol);
    if (targetItem) {
      // 已存在该symbol,累加数量后转回字符串
      targetItem.fulfilledQty = (parseFloat(targetItem.fulfilledQty) + parseFloat(curr.fulfilledQty)).toString();
    } else {
      // 不存在则新增条目
      acc.push({...curr});
    }
    return acc;
  }, []);

console.log(result);

写法二:先聚合为对象再转数组(性能更优)

利用对象键查找的O(1)特性,比数组find的O(n)效率更高:

const result = Object.entries(
  orders.flatMap(o => o.subOrders)
    .reduce((acc, {symbol, fulfilledQty}) => {
      // 累加对应symbol的数量,初始值为0
      acc[symbol] = (acc[symbol] || 0) + parseFloat(fulfilledQty);
      return acc;
    }, {})
).map(([symbol, fulfilledQty]) => ({
  symbol,
  fulfilledQty: fulfilledQty.toString() // 转回字符串格式
}));

console.log(result);

代码说明

  1. flatMap:一次性将嵌套的subOrders数组展开为一维数组,省去手动嵌套循环。
  2. reduce:核心的聚合逻辑,两种写法分别对应「直接操作目标数组」和「先对象聚合再转数组」的思路。
  3. 类型处理:始终保持fulfilledQty的字符串格式,和期望结果一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 07:40:33