映射出 JSON 结构

Mapping out JSON structure

我正在解析一条 JSON 消息,它类似于:

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

我想从中提取每个单独值的数组。 即

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

目前我正在做类似

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

这感觉过于冗长,只是想知道是否有更简洁的方法来解决这个问题(对于每个属性)。我已经在这个项目中包含了 lodash。

编辑 错过了你有可用的 lodash,无论如何都会在这里留下这个 vanilla JS 版本。

你可以使用地图更简洁:

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

如果您事先不知道各个键的名称,您可以这样做:

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

我没有理解获取存储在每个键下的所有值的数组的要求,不过应该这样做:

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;
}, {});

这个returns以下:

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

你的直觉是对的;使用 lodash 不需要可变数组。

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

此版本适用于 o 中任意数量的数组值。

JSBin

您可以使用 _.pluck 获取数组中每个对象的 属性 的值:

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