HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Getting a substructure in a JSON-file

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
jsonfilesubstructuregetting

Problem

I'm currently playing with D3.js.

While doing so I use this JSON-file as a data source: http://codepen.io/chriscoyier/pen/taqCe

Example of the structure:

{
  "fathers" : [
    {
      "id" : 0,
      "married" : false,
      "name" : "Robert Wilson",
      "sons" : null,
      "daughters" : [
        {
          "age" : 21,
          "name" : "Nancy"
          },
        {
          "age" : 30,
          "name" : "Amy"
          }
        ]
      },
    {
      "id" : 1,
      "married" : true,
      "name" : "Robert Thomas",
      "sons" : null,
      "daughters" : [
        {
          "age" : 22,
          "name" : "Melissa"
          },
        {
          "age" : 6,
          "name" : "Susan"
          }
        ]
      },
      ...
    ]
  }


I'm only interested in "daughters".
I have mapped the objects into a flat array structure.
The code I used:

var fathers = data.fathers,
      separator = '-------------------',
      persons = []; // collector array

   // Filling the collector array with the 
   //   desired data.
   fathers.forEach(function(value) {

     value['daughters'].forEach(function(value) {
       persons.push(value);
     });

   });


It works fine. My complete code here: http://codepen.io/mizech/pen/WrNzJe

But I wonder:
Aren't there better ways (in native JavaScript, no frameworks) then iterating?

Would be pleased if anyone has an idea and would share it.

Solution

The operation you want is called flatMap, SelectMany, or concatMap (I might have missed a few names.)


Map a function over a collection and flatten the result by one-level

As far as I'm aware, this isn't provided out-of-the-box but I found an implementation here:

Array.prototype.flatMap = function(lambda) { 
  return Array.prototype.concat.apply([], this.map(lambda)); 
};


Then you can just write

var persons = data.fathers.flatMap(function(father) { return father.daughters; });


Or if you can use arrow functions,

var persons = data.fathers.flatMap(father => father.daughters);

Code Snippets

Array.prototype.flatMap = function(lambda) { 
  return Array.prototype.concat.apply([], this.map(lambda)); 
};
var persons = data.fathers.flatMap(function(father) { return father.daughters; });
var persons = data.fathers.flatMap(father => father.daughters);

Context

StackExchange Code Review Q#112969, answer score: 3

Revisions (0)

No revisions yet.