Search code examples
javascriptarraysobjectarray-merge

How to merge duplicate object parent items in array?


I want to merge objects in array so that objects with the same id (which is a child object) can sum the total_price and total_quantity values. Here is my data array:

var data = [
        {
            "_id": {
                "month": 5,
                "year": 2021
            },
            "total_price": 145111500,
            "total_quantity": 7
        },
        {
            "_id": {
                "month": 6,
                "year": 2021
            },
            "total_price": 98386000,
            "total_quantity": 5
        },
        {
            "_id": {
                "month": 6,
                "year": 2021
            },
            "total_price": 32500000,
            "total_quantity": 3
        }
    ]

I want to merge objects that have the duplicate "_id". Here is the output result:

var merge = [
        {
            "_id": {
                "month": 5,
                "year": 2021
            },
            "total_price": 145111500,
            "total_quantity": 7
        },
        {
            "_id": {
                "month": 6,
                "year": 2021
            },
            "total_price": 130886000,
            "total_quantity": 8
        }
    ]

Thanks in advance.


Solution

  • const data = [
      { "_id": { "month": 5, "year": 2021 }, "total_price": 145111500, "total_quantity": 7 },
      { "_id": { "month": 6, "year": 2021 }, "total_price": 98386000, "total_quantity": 5 },
      { "_id": { "month": 6, "year": 2021 }, "total_price": 32500000, "total_quantity": 3 }
    ];
    
    const res = [...
      // iterate over the list
      data.reduce((map, item) => {
        // construct key from _id
        const key = `${item._id.month}-${item._id.year}`;
        // get prev map value of key if exists
        const prev = map.get(key);
        // update map, if prev not found, set value as item, or update it with the added values
        map.set(
          key, 
          !prev 
            ? item 
            : { ...item, total_price: prev.total_price + item.total_price, total_quantity: prev.total_quantity + item.total_quantity }
        );
        return map;
      }, new Map)
      // return map values
      .values()
    ];
    
    console.log(res);