JSON structure mapping

I am parsing a JSON message that looks something like this:

{ 
    staff : [
       {name : 'John', department : 'Math'},
       {name : 'Sally', department : 'Science'},
    ],
    students : [
       {name : 'Bob', department : 'Law'},
       {name : 'Lisa', department : 'IT'}
    ]
}

      

From which I would like to extract an array of each distinct value. i.e.

names -> ['John', 'Sally', 'Bob', 'Lisa']

      

At the moment I am doing something like

var names = [];
msg.staff.forEach(function(e) { names.push(e.name) })
msg.students.forEach(function(e) { names.push(e.name)})

      

This seems overly verbose, just wondering if there is a cleaner way to approach this (for each attribute). I am already including lodash in this project.

+3


source to share


3 answers


You can use _.pluck

to get the property value of each object in an array:



_.pluck(obj.staff.concat(obj.students), 'name')

      

+2


source


Your instinct is right; you don't need a mutable array to do this with lodash.

_(obj).map().flatten().pluck('name').value();

      



This version works for any number of array values ​​in o

.

JSBin

+1


source


Change missed that you have lodash available will leave that Vanilla JS version anyway.

You can use a map to be more concise:

var directory = { 
    staff : [
       {name : 'John', department : 'Math'},
       {name : 'Sally', department : 'Science'},
    ],
    students : [
       {name : 'Bob', department : 'Law'},
       {name : 'Lisa', department : 'IT'}
    ]
};

var names = directory.staff.concat(directory.students).map(function(person) {
   return person.name;
});

      

If you don't know the names of the individual keys in front of the hand, you can do:

Object.keys(directory).map(function(key) { 
  return directory[key] 
}).reduce(function(p,c){ 
  return p.concat(c) 
}).map(function(person) {
   return person.name;
});

      

I didn't catch the requirement to get an array of all the values ​​stored under each key, this should do it, though:

Object.keys(directory).map(function(key) { 
  return directory[key];
}).reduce(function(p,c) { 
  return p.concat(c);
}).reduce(function(p, c) {
   Object.keys(c).forEach(function(oKey) {
     if(p[oKey]) p[oKey].push(c[oKey]);
     else p[oKey] = [c[oKey]];
   });
   return p;
}, {});

      

This returns the following:

{
  "name":["John","Sally","Bob","Lisa"],
  "department": ["Math","Science","Law","IT"]
}

      

0


source







All Articles