Sagar Chavan
Sagar Chavan

Reputation: 259

merge same properties of array of objects and create array of object within that array of object for different properties

This is my array

"status": "Success",
    "results": 54,
    "orders": [
        {
            "order_id": 261,
            "image": "test1.png",
            "productName": "test1",
            "price": 2,
            "quantity": 2,
            "purAmt": 34,
            "created_at": "2020-07-27T06:29:32.000Z",
            "shopName": "abc"
        },
        {
            "order_id": 261,
            "image": "test2.png",
            "productName": "test2",
            "price": 30,
            "quantity": 1,
            "purAmt": 34,
            "created_at": "2020-07-27T06:29:32.000Z",
            "shopName": "abc"
        },
]

I want to combine properties with same name and create array of object within a object.

expected output

    "status": "Success",
        "results": 54,
        "orders": [
            {
                "order_id": 261,
                "purAmt": 34,
                "created_at": "2020-07-27T06:29:32.000Z",
                "shopName": "abc"
                products : [
{
                     "productName": "test1",
                     "price": 2,
                     "quantity": 2,
                     "image": "test1.png",
},
{
                     "productName": "test2",
                     "price": 5,
                     "quantity": 3,
                     "image": "test2.png",
},
            }
    ]

I would be better if I get the solution using reduce function and without any libraries like lodash

My attempt of doing it using reduce fcn

var result = Object.values(
                data.reduce(
                    (acc, { productName, price, image, quantity, ...rest }) => {
                        acc[rest.orderID] = acc[rest.orderID] || { ...rest, products: [] };
                        acc[rest.orderID].products.push({
                            productName,
                            price,
                            image,
                            quantity,
                        });
                        return acc;
                    },
                    {},
                ),
            );

Upvotes: 0

Views: 49

Answers (2)

Sascha A.
Sascha A.

Reputation: 4616

Extended Version: I extend it, so there are now different order_id's considered. For example I add a id 262 which creates another element in orders-array.

let data = { "status": "Success",
    "results": 54,
    "orders": [
        {
            "order_id": 261,
            "image": "test1.png",
            "productName": "test1",
            "price": 2,
            "quantity": 2,
            "purAmt": 34,
            "created_at": "2020-07-27T06:29:32.000Z",
            "shopName": "abc"
        },
        {
            "order_id": 262,
            "image": "test3.png",
            "productName": "test3",
            "price": 70,
            "quantity": 5,
            "purAmt": 17,
            "created_at": "2020-07-19T06:29:32.000Z",
            "shopName": "xyz"
        },
        {
            "order_id": 261,
            "image": "test2.png",
            "productName": "test2",
            "price": 30,
            "quantity": 1,
            "purAmt": 34,
            "created_at": "2020-07-27T06:29:32.000Z",
            "shopName": "abc"
        },
]};

let orderIndex =[];

let orders = [];
data.orders.forEach(orderObj => {
    let order;
    let index = orderIndex.indexOf(orderObj.order_id);
    if (index == -1) {
        orderIndex.push(orderObj.order_id);
        order = {};
        orders.push(order);
        ['order_id', 'purAmt', 'created_at', 'shopName'].forEach( elem => {
            order[elem] = orderObj[elem];
            order.products = [];
        });
    } else {
        order = orders[index];
    }
    let product = {};
    ['productName', 'price', 'image', 'quantity'].forEach( elem => {
        product[elem] = orderObj[elem];
    });
    order.products.push(product);
});

let result = {
    status: data.status,
    results: data.results,
    orders: orders
}

console.log(result);

Upvotes: 1

Siva Kondapi Venkata
Siva Kondapi Venkata

Reputation: 11001

This should work for you

orders = [
  {
    order_id: 261,
    image: "test1.png",
    productName: "test1",
    price: 2,
    quantity: 2,
    purAmt: 34,
    created_at: "2020-07-27T06:29:32.000Z",
    shopName: "abc",
  },
  {
    order_id: 261,
    image: "test2.png",
    productName: "test2",
    price: 30,
    quantity: 1,
    purAmt: 34,
    created_at: "2020-07-27T06:29:32.000Z",
    shopName: "abc",
  },
];

const res = Object.values(
  orders.reduce((acc, { image, productName, price, quantity, ...rest }) => {
    if (!acc[rest.order_id]) {
      acc[rest.order_id] = { products: [] };
    }
    acc[rest.order_id] = {
      ...acc[rest.order_id],
      ...rest,
      products: [
        ...acc[rest.order_id].products,
        {
          image,
          productName,
          price,
          quantity,
        },
      ],
    };

    return acc;
  }, {})
);

console.log(res);

Upvotes: 1

Related Questions