James Ives
James Ives

Reputation: 3365

Flattening array of arrays with reduce

I have an array of objects which I'd like to restructure with reduce but I'm having some difficulties figuring out the correct way to do this. The data looks like this:

[ { name: 'Item', accounts: [ { value: 1 }, { value: 2 }, { value: 3}] },
{ name: 'Item', accounts: [ { value: 1 }, { value: 2 }, { value: 3}] },
{ name: 'Item', accounts: [ { value: 1 }, { value: 2 }, { value: 3}] },
{ name: 'Item2', accounts: [ { value: 1 }, { value: 2 }, { value: 3}] },
{ name: 'Item2', accounts: [ { value: 1 }, { value: 2 }, { value: 3}] },
{ name: 'Item2', accounts: [ { value: 1 }, { value: 2 }, { value: 3}] } ],

What I'd like to do is restructure this array so it groups all items by the name, and flattens the array of accounts. Resulting in something like this;

[
 {
  name: 'Item',
  accounts: [ { value: 1 }, { value 2 } ] //.. Includes all account objects that had the  name 'Item' 
 },

 {
  name: 'Item 2',
  accounts: [  { value: 1 }, { value: 2 } ] //.. Includes all account object that had the name 'Item2'
 }
]

I've attempted to do this with the following code, but I'm running into issues and the structure isn't quite what I'm looking for.

accounts.reduce((obj, item) => { 
  obj.accounts[item.name] = obj.accounts[item.name] || {
    name: item.name,
    accounts: [],
  }

 obj.accounts[item.name].accounts.push(item.accounts);

 return obj;

}, {accounts: {}})

What would be the correct way to perform this?

Upvotes: 1

Views: 79

Answers (1)

Nina Scholz
Nina Scholz

Reputation: 386604

You could push a spreaded array to accounts and take the values of the object after grouping.

var accounts = [{ name: 'Item', accounts: [{ value: 1 }, { value: 2 }, { value: 3 }] }, { name: 'Item', accounts: [{ value: 1 }, { value: 2 }, { value: 3 }] }, { name: 'Item', accounts: [{ value: 1 }, { value: 2 }, { value: 3 }] }, { name: 'Item2', accounts: [{ value: 1 }, { value: 2 }, { value: 3 }] }, { name: 'Item2', accounts: [{ value: 1 }, { value: 2 }, { value: 3 }] }, { name: 'Item2', accounts: [{ value: 1 }, { value: 2 }, { value: 3 }] }],
    grouped = Object.values(accounts.reduce((obj, { name, accounts }) => {
        obj[name] = obj[name] || { name, accounts: [] };
        obj[name].accounts.push(...accounts);
        return obj;
    }, {}));

console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

Related Questions