anie
anie

Reputation: 529

Grouping nested arrays data by specific key

I have array list as follow:

let data =[
    {
        "id": "05a87dssff-7468-49b1-bae3-0cd06dc22189",
        "details": [
            [
                {
                    "Id": "6741c8b3-03bb-4431-9975-df25eae0a5c2",
                    "qty": 4,
                    "name": "chicken burger",
                    "price": 15,
                    "total": "60.00",
                    
                }
            ]
        ],
    },
    {
        "id": "05a87dff-746gf-49b1-bae3-s0cd06dc22189",
        "details": [
            [
                {
                    "Id": "6741c8b3-03bb-4431-9975-df25eae0a5c2",
                    "qty": 4,
                    "name": "chicken burger",
                    "price": 15,
                    "total": "60.00",
                    
                }
            ]
        ],
    },
    
    {
        "id": "06129f89-dd80-49dd-bf5d-a12764c23949",
        "details": [
            [
                {
                    "Id": "6741c8b3-03bb-4431-9975-df25eae0a5c2",
                    "qty": 4,
                    "name": "Beef burger",
                    "price": 15,
                    "total": "60.00",
                }
            ],
            [
                 {
                    "Id": "6741c8b3-03bb-4431-9975-df25eae0a5c2",
                    "qty": 4,
                    "name": "Beef burger",
                    "price": 15,
                    "total": "60.00",
                }
            ],
            [
                {
                    "Id": "6741c8b3-03bb-4431-9975-df25eae0a5c2",
                    "qty": 4,
                    "name": "chicken burger",
                    "price": 15,
                    "total": "60.00",
                }
            ]
        ],
    }
]

I am trying to group all the arrays that have same name and then sum the values of the properties that have the same name in one grand total, so the expected result based on the above array is:

 [{'name':'chicken burger', 'total': 180},{'name':'Beef burger', 'total': 120}]

What i have tried is the following however, it keeps giving me the all array separated not grouped, here is what i have done so far:

    data.map(a => a.details.map(b => b.reduce((d,e)=> {
  const newArr = d;
  if (d.length && d[d.length - 1]['name'] === e['name']) 
      newArr[d.length - 1] =
      {
        //...d[d.length - 1], ...e,
        total: parseFloat(d[d.length - 1].d) + parseFloat(e.total),
      }
    else newArr[d.length] = { ...e }
    
   console.log(newArr)
    return newArr;
},[]) ) );

and here a link to the code

Upvotes: 0

Views: 55

Answers (2)

zb22
zb22

Reputation: 3231

You can use Array.prototype.map() to get the names and totals from the all the details arrays.

Then, use Array.prototype.reduce() in order to group the names.

let data = [
    {
        "id": "05a87dssff-7468-49b1-bae3-0cd06dc22189",
        "details": [
            [
                {
                    "Id": "6741c8b3-03bb-4431-9975-df25eae0a5c2",
                    "qty": 4,
                    "name": "chicken burger",
                    "price": 15,
                    "total": "60.00",
                }
            ]
        ],
    },
    {
        "id": "05a87dff-746gf-49b1-bae3-s0cd06dc22189",
        "details": [
            [
                {
                    "Id": "6741c8b3-03bb-4431-9975-df25eae0a5c2",
                    "qty": 4,
                    "name": "chicken burger",
                    "price": 15,
                    "total": "60.00",
                    
                }
            ]
        ],
    },
    {
        "id": "06129f89-dd80-49dd-bf5d-a12764c23949",
        "details": [
            [
                {
                    "Id": "6741c8b3-03bb-4431-9975-df25eae0a5c2",
                    "qty": 4,
                    "name": "Beef burger",
                    "price": 15,
                    "total": "60.00",
                }
            ],
            [
                 {
                    "Id": "6741c8b3-03bb-4431-9975-df25eae0a5c2",
                    "qty": 4,
                    "name": "Beef burger",
                    "price": 15,
                    "total": "60.00",
                }
            ],
            [
                {
                    "Id": "6741c8b3-03bb-4431-9975-df25eae0a5c2",
                    "qty": 4,
                    "name": "chicken burger",
                    "price": 15,
                    "total": "60.00",
                }
            ]
        ],
    }
]

const namesAndTotals = data.flatMap(item => item.details.flat().map(({ name, total }) => ({ name, total: Number(total) })));

const res = Object.values(namesAndTotals.reduce((acc, { name, total }) => {
  if(!acc[name]) {
    acc[name] = {
      name,
      total
    }
  } else {
    acc[name].total += total;
  }

  return acc;
}, {}));

console.log(res);

Upvotes: 0

ProDec
ProDec

Reputation: 5410

Iterate over the array, using Map to store calculated sum.

let data =[ { "id": "05a87dssff-7468-49b1-bae3-0cd06dc22189", "details": [ [ { "Id": "6741c8b3-03bb-4431-9975-df25eae0a5c2", "qty": 4, "name": "chicken burger", "price": 15, "total": "60.00", } ] ], }, { "id": "05a87dff-746gf-49b1-bae3-s0cd06dc22189", "details": [ [ { "Id": "6741c8b3-03bb-4431-9975-df25eae0a5c2", "qty": 4, "name": "chicken burger", "price": 15, "total": "60.00", } ] ], }, { "id": "06129f89-dd80-49dd-bf5d-a12764c23949", "details": [ [ { "Id": "6741c8b3-03bb-4431-9975-df25eae0a5c2", "qty": 4, "name": "Beef burger", "price": 15, "total": "60.00", } ], [ { "Id": "6741c8b3-03bb-4431-9975-df25eae0a5c2", "qty": 4, "name": "Beef burger", "price": 15, "total": "60.00", } ], [ { "Id": "6741c8b3-03bb-4431-9975-df25eae0a5c2", "qty": 4, "name": "chicken burger", "price": 15, "total": "60.00", } ] ] }];

const map = new Map();

data.forEach(
  item => item.details.forEach(
    detail => {
      const {name, total} = detail[0];
      map.has(name) ? map.get(name).total += +total : map.set(name, {name, total: +total})
    }
  )
);

const result = [...map.values()];

console.log(result);

Upvotes: 2

Related Questions