skip to Main Content

I have an javascript array and it contains another array of objects. Now I want to do sum of the field of objects having same symbol key.
How to do that ?

The array I have

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

The array I want from above array

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

So I want to the sum of fulfilledQty of same symbol

I tried this


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);
         }
}

That gives me this object

{SUZ: "59.085449695", FSLR: "4.483638999"} 

then I will convert it to array.
Because Inside inner for loop I will have to put another loop to compare the symbols So this will not iterate each time to compare symbols
That can be achieved using the loops but do so I will have to iterate the arrays too many times
Is there any simpler way to do so ?

3

Answers


  1. You can use a .reduce() to sum up the qty by symbol, then map that into the desired array:

    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);
    Login or Signup to reply.
  2. We can use Array.flatMap() and Array.reduce() to do it

    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)
    Login or Signup to reply.
  3. As you have mentioned you are getting the array from mongodb then you can make a aggregation pipeline.

                  let aggregation = [
                        {
                          '$match': {
                             //Your query here
                           }
                        }, {
                          '$unwind': {
                            'path': '$subOrders'
                          }
                        }, {
                          '$group': {
                            '_id': '$symbol', 
                            'symbol': {'$first': "$symbol"},
                            'total': {
                              '$sum': {
                                '$toDouble': '$fulfilledQty'
                              }
                            }
                          }
                        }
                      ]
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search