kyle
kyle

Reputation: 527

What's a terse es6 way of flattening a nested object?

For example, turn this:

const enums = { ip: 'ip', er: 'er' };

const obj = {
  somethingNotNeeded: {...},
  er: [
    { a: 1},
    { b: 2}
  ],
  somethingElseNotNeeded: {...},
  ip: [
    { a: 1},
    { b: 2}
  ]
}

Into this:

[
  { a: 1},
  { b: 2},
  { a: 1},
  { b: 2}
]

I'm already doing this in a roundabout way by declaring an enum object of the types i want (er, ip) then doing a forEach (lodash) loop on obj checking if the keys aren't in the enum and delete them off the original obj. Then having just the objects I want, I do two nested forEach loops concatenating the results to a new object using object rest spread...

I'm almost entirely sure there's a better way of doing this but I didn't think of it today.

Upvotes: 3

Views: 839

Answers (3)

Ori Drori
Ori Drori

Reputation: 191986

Get the enums properties with Object.values() (or Object.keys() if they are always identical). Use Array.map() to iterate the array of property names, and extract their values from obj. Flatten the array of arrays by spreading it into Array.concat():

const enums = { ip: 'ip', er: 'er' };

const obj = {
  somethingNotNeeded: {},
  er: [
    { a: 1},
    { b: 2}
  ],
  somethingElseNotNeeded: {},
  ip: [
    { a: 1},
    { b: 2}
  ]
};

const result = [].concat(...Object.values(enums).map(p => obj[p]));

console.log(result);

Upvotes: 1

Giri
Giri

Reputation: 275

Since you're not using the key of the enums in the final output, we could simply use an Array instead of an object.

const enums = ['ip', 'er'];

const obj = {
  somethingNotNeeded: {},
  er: [
    { a: 1 },
    { b: 2 },
  ],
  somethingElseNotNeeded: {},
  ip: [
    { a: 1 },
    { b: 2 }
  ]
};

const result = enums.reduce((acl, curr) => acl.concat(obj[curr]), []);
console.log(result);  

This should do the trick.

Upvotes: 0

Adrian Brand
Adrian Brand

Reputation: 21638

const props = ['ip', 'er']; // An array of the properties you are interested in

const obj = {
  somethingNotNeeded: {},
  er: [
    { a: 1},
    { b: 2}
  ],
  somethingElseNotNeeded: {},
  ip: [
    { a: 1},
    { b: 2}
  ]
}

const flatten = (array) => array ? array.reduce((output, array) => [...output, ...array], []) : array; // Take an array of arrays and flatten it into a single array

const result = flatten(props.map(p => obj[p])); //Run the flattern over an array that has been created by mapping the property names

console.log(result)

Upvotes: 0

Related Questions