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

Viewed 806

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.

3 Answers

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);

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)

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.

Related