Skip to content
Advertisement

How to group nested array of objects in js

I have a nested array of objects. I’m trying to group product objects that have the same value.

Each objects has a vendor property containing an email. I am trying to group the objects by matching vendor email

This is how my database looks like:

[
        {
            _id: "622d70a49bd88b1599026318",
            products: [
                {
                    _id: "6223186e2278d4e502f5264a",
                    title: "Product number 1",
                    price: 600,
                    cartQuantity: 1,
                    vendor: {email: "vendor1@gmail.com"}
                },
                {
                    _id: "622d4e9f9bd88b1599026317",
                    title: "asdas",
                    price: 100,
                    cartQuantity: 5,
                    vendor: {
                        email: "vendor2@gmail.com"
                    }
                },
                 {
                    _id: "622d4e9f9bd88b1599026317",
                    title: "asdas",
                    price: 100,
                    cartQuantity: 5,
                    vendor: {
                        email: "vendor2@gmail.com"
                    }
                }
            ]
        }]

I am trying to do it with the reduce method but the problem is with using map inside the reduce. It repeats the object many times. I am also unable to get the grouped objects.

const groupedMap = db.reduce(
    (entryMap, e) => e.products.map((product) => entryMap.set(product.vendor.email, [...entryMap.get(product)||[], product])),
    new Map()
);

The above code output is: enter image description here

My expectation is:

[0: {"vendor1@gmail.com" => Array(1)}
   key: "vendor1@gmail.com"
   value: [{_id: '6223186e2278d4e502f5264a', title: 'Product number 1', price: 600, cartQuantity: 1, vendor: {email: "vendor1@gmail.com"}}],
1: {"vendor2@gmail.com" => Array(2)}
key: "vendor2@gmail.com"
   value: [{_id: '6223186e2278d4e502f5264a', title: 'Product number 1', price: 600, cartQuantity: 1, vendor: {email: "vendor2@gmail.com"}},
{_id: '6223186e2278d4e502f5264a', title: 'Product number 1', price: 600, cartQuantity: 1, vendor: {email:"vendor2@gmail.com"}}
]
]

Advertisement

Answer

Loop through each item in the array and see if the vendor email exists as a key already in a dictionary, if it exists push it to that array, otherwise set the value of the vendor email key equal to an array with the current item in it

See code below

const data = [{
  _id: "622d70a49bd88b1599026318",
  products: [{
      _id: "6223186e2278d4e502f5264a",
      title: "Product number 1",
      price: 600,
      cartQuantity: 1,
      vendor: {
        email: "vendor1@gmail.com"
      }
    },
    {
      _id: "622d4e9f9bd88b1599026317",
      title: "asdas",
      price: 100,
      cartQuantity: 5,
      vendor: {
        email: "vendor2@gmail.com"
      }
    },
    {
      _id: "622d4e9f9bd88b1599026317",
      title: "asdas",
      price: 100,
      cartQuantity: 5,
      vendor: {
        email: "vendor2@gmail.com"
      }
    }
  ]
}];

const mapped = {};
data[0].products.forEach(item => {
  if (item.vendor.email in mapped) return mapped[item.vendor.email].push(item);

  mapped[item.vendor.email] = [item];
});

const expectedFormat = Object.keys(mapped).map(key => {
  const o = {};
  o[key] = mapped[key];
  
  return o;
});

console.log(expectedFormat)
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement