Extracting data in ES6 I have this array const idArray = ["12", "231", "73", "4"] and an object

const blueprints = {
  12: {color: red, views: [{name: "front}, {name: "back}, {name: "top}, {name: "bottom}]},
  231: {color: white, views: [{name: "front}, {name: "back}]},
  73: {color: black, views: [{name: "front}, {name: "back}, {name: "top}, {name: "bottom}]},
  4: {color: silver, views: [{name: "front}, {name: "back}, {name: "top}, {name: "bottom}]},
}


How can I return an array of the following objects that have all front, back, top, and bottom using ES6 map/filter/some and etc?:

result =[
    {colorId: "12", views: [{name: "front}, {name: "back}, {name: "top}, {name: "bottom}]}
    {colorId: "73", views: [{name: "front}, {name: "back}, {name: "top}, {name: "bottom}]}
    {colorId: "4", views: [{name: "front}, {name: "back}, {name: "top}, {name: "bottom}]}
]


I did it here but I feel like it is too messy and hard to read. Anybody could recommend on how to shorten it and make it easier to read using the ES6 functions (map, filter ...)?

const result = idArray.map(id =&gt; {
      const bluePrint = bluePrints[id];
      const exists = bluePrint.views.some(view =&gt; view.name === 'top' || view.name === 'bottom');

      if (exists) {
        return {
          colorId: id,
          views: bluePrint.views
        }
      }
    }).filter(bluePrint =&gt; bluePrint);
The initial data is not formatted as proper JSON. There appear to be mismatched quotes around values like front, back, etc... try running the snippet below to see the error that is caused by this.


const blueprints = {
  12: {color: red, views: [{name: "front}, {name: "back}, {name: "top}, {name: "bottom}]},
  231: {color: white, views: [{name: "front}, {name: "back}]},
  73: {color: black, views: [{name: "front}, {name: "back}, {name: "top}, {name: "bottom}]},
  4: {color: silver, views: [{name: "front}, {name: "back}, {name: "top}, {name: "bottom}]},
}
 



Also, unless red, white, black and silver are defined as variables, they need to be enclosed in quotes as string literals. See the rewrite below for a sample of this.

The indentation is inconsistent- the first level in the .map() callback is four spaces and then two spaces within the if block. Stick with one or the other.

You could use Array.prototype.reduce() to conditionally add the desired elements to an output array, reducing the need to call .filter():
const result = idArray.reduce((output,id) =&gt; {
  const bluePrint = bluePrints[id];
  //conditionally add to output and then return it
  return output;
}, []);

You could also use Object.keys() to iterate over the keys of bluePrints instead of idArray, though it appears to be slightly slower (see performance link below).
const result = Object.keys(bluePrints).reduce((output,id) =&gt; {
  const bluePrint = bluePrints[id];
  //conditionally add to output and then return it
  return output;
}, []);

See a comparison of the three snippets in this jsPerf.

One other change for readability would be to move that filter function outside the call to .map() or .reduce():
const viewIsTopOrBottom = view =&gt; view.name === 'top' || view.name === 'bottom'

Then that function can be called within the call to .some():
const exists = bluePrint.views.some(viewIsTopOrBottom);

And then that boolean exists could be eliminated by moving the call to .some() into the conditional statement of the if:
if (bluePrint.views.some(viewIsTopOrBottom)) {
  //add to array


Proposed Rewrite


const idArray = ["12", "231", "73", "4"];
  const bluePrints = {
    12: {color: "red", views: [{name: "front"}, {name: "back"}, {name: "top"}, {name: "bottom"}]},
    231: {color: "white", views: [{name: "front"}, {name: "back"}]},
    73: {color: "black", views: [{name: "front"}, {name: "back"}, {name: "top"}, {name: "bottom"}]},
    4: {color: "silver", views: [{name: "front"}, {name: "back"}, {name: "top"}, {name: "bottom"}]},
  };
const viewIsTopOrBottom = view =&gt; view.name === 'top' || view.name === 'bottom';
const result = idArray.reduce((output,id) =&gt; {
  const bluePrint = bluePrints[id];
  if (bluePrint.views.some(viewIsTopOrBottom)) {
    output.push({
      colorId: id,
      views: bluePrint.views
    });
  }
  return output;
}, []);
console.log('result,', result);