Pengguna
Pengguna

Reputation: 4941

How to flatten and merge nested array from each of child array

So i have this data:

let data = [
  {
    "purchase_id": 1,
    "product": [
      {
        "name": "A",
        "id": 1,
        "transactions": [
          {
            "price": 5,
            "qty": 2
          },
          {
            "price": 10,
            "qty": 2
          }
        ]
      },
      {
        "name": "B",
        "id": 2,
        "transactions": [
          {
            "price": 3,
            "qty": 4
          }
        ]
      }
    ]
  },
  {
    "purchase_id": 2,
    "product": [
      {
        "name": "C",
        "id": 3,
        "transactions": [
          {
            "price": 5,
            "qty": 2
          }
        ]
      },
      {
        "name": "D",
        "id": 4,
        "transactions": [
          {
            "price": 3,
            "qty": 4
          }
        ]
      }
    ]
  }
]

And i want to flatten array from each data.product.transactions data:

"transactions": [
    {
       "price",
       "qty"
    }
 ]

Expected output is:

[
  {
    "purchase_id": 1,
    "name": "A",
    "id": 1,
    "price": 5,
    "qty": 2
  },
  {
    "purchase_id": 1,
    "name": "A",
    "id": 1,
    "price": 10,
    "qty": 2
  },
  {
    "purchase_id": 1,
    "name": "B",
    "id": 2,
    "price": 3,
    "qty": 4
  },
  {
    "purchase_id": 2,
    "name": "C",
    "id": 3,
    "price": 5,
    "qty": 2
  },
  {
    "purchase_id": 2,
    "name": "D",
    "id": 4,
    "price": 3,
    "qty": 4
  },
]

I have tried to use object assign, reduce but my code doesn't work. Thank you

Upvotes: 1

Views: 75

Answers (2)

Rahul Bisht
Rahul Bisht

Reputation: 144

var arr = [];
data.forEach(x => {
  x.product.forEach(y => {
    y.transactions.forEach(z => {
      z["name"] = y.name;
      z["id"] = y.id;
      z["purchase_id"] = x.purchase_id;
      arr.push(z);
    });
  })
});
console.log(arr);

Upvotes: 1

Ori Drori
Ori Drori

Reputation: 191976

Use nested Array.map() to create the objects, and spread into Array.concat() to flatten the sub-arrays at each level:

const data = [{"purchase_id":1,"product":[{"name":"A","id":1,"transactions":[{"price":5,"qty":2},{"price":10,"qty":2}]},{"name":"B","id":2,"transactions":[{"price":3,"qty":4}]}]},{"purchase_id":2,"product":[{"name":"C","id":3,"transactions":[{"price":5,"qty":2}]},{"name":"D","id":4,"transactions":[{"price":3,"qty":4}]}]}];

const result = [].concat(...data.map(({ purchase_id, product }) => 
  [].concat(...product.map(({ name, id, transactions }) => 
    transactions.map((o) => ({
      purchase_id,
      name,
      id,
      ...o
    })
)))));

console.log(result);

If you want to avoid the temp sub-arrays, and the flattering, use nested Array.forEach() calls, and push the created objects to a predefined array:

const data = [{"purchase_id":1,"product":[{"name":"A","id":1,"transactions":[{"price":5,"qty":2},{"price":10,"qty":2}]},{"name":"B","id":2,"transactions":[{"price":3,"qty":4}]}]},{"purchase_id":2,"product":[{"name":"C","id":3,"transactions":[{"price":5,"qty":2}]},{"name":"D","id":4,"transactions":[{"price":3,"qty":4}]}]}];

const result = [];

data.forEach(({ purchase_id, product }) => 
  product.forEach(({ name, id, transactions }) => 
    transactions.forEach((o) => result.push({
      purchase_id,
      name,
      id,
      ...o
    })
)));

console.log(result);

Upvotes: 1

Related Questions