javascript 从具有相同属性的对象数组的数组生成数组

uqjltbpv  于 2022-12-10  发布在  Java
关注(0)|答案(3)|浏览(112)

我有一个javascript数组,它包含了另一个对象数组。现在我想对具有相同符号键的对象的字段求和。怎么做?
我拥有的数组

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"
    }
]

所以我想得到fulfilledQty的和
我试过这个

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"}

然后我会把它转换成数组,因为在内部for循环里我会放另一个循环来比较符号,所以这不会每次都迭代来比较符号,这可以用循环来实现,但是这样做的话,我会迭代数组太多次,有更简单的方法吗?

lsmd5eda

lsmd5eda1#

可以使用.reduce()按符号对数量求和,然后将其Map到所需的数组中:

const input = [
  {
    "_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" }
    ]
  }
];
let sums = input.reduce((acc, obj) => {
  obj.subOrders.forEach(item => {
    let symbol = item.symbol;
    let qty = Number(item.fulfilledQty);
    if(!acc[symbol]) {
      acc[symbol] = qty;
    } else {
      acc[symbol] += qty;
    }
  });
  return acc;
}, {});
let result = Object.keys(sums).sort().map(symbol => {
  return {
    symbol: symbol,
    fulfilledQty: sums[symbol].toString()
  };
});
console.log(result);
gstyhher

gstyhher2#

正如您所提到的,您从mongodb获取数组,然后可以创建一个聚合管道。

let aggregation = [
                    {
                      '$match': {
                         //Your query here
                       }
                    }, {
                      '$unwind': {
                        'path': '$subOrders'
                      }
                    }, {
                      '$group': {
                        '_id': '$symbol', 
                        'symbol': {'$first': "$symbol"},
                        'total': {
                          '$sum': {
                            '$toDouble': '$fulfilledQty'
                          }
                        }
                      }
                    }
                  ]
au9on6nz

au9on6nz3#

我们可以使用Array.flatMap()Array.reduce()来实现

let result = orders.flatMap(e => e.subOrders).reduce((a,{symbol,fulfilledQty}) => {
  a[symbol] = a[symbol]??0
  a[symbol] += +fulfilledQty
  return a
},{})
console.log(result)
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"
            }
        ]
    }
]

let result = orders.flatMap(e => e.subOrders).reduce((a,{symbol,fulfilledQty}) => {
  a[symbol] = a[symbol]??0
  a[symbol] += +fulfilledQty
  return a
},{})
console.log(result)

相关问题