使用 Underscore 将嵌套的 JSON 展平为键值数组
Flatten nested JSON into a keyed array of values using Underscore
从我的服务器 API,我请求一个具有以下结构的 javascript 对象:
[
{
"msgID": 3,
"admTag": {
"tagName": "Employee"
}
},
{
"msgID": 3,
"admTag": {
"tagName": "Safety"
}
},
{
"msgID": 3,
"admTag": {
"tagName": "Performance"
}
},
{
"msgID": 7,
"admTag": {
"tagName": "Role Based Training"
}
},
{
"msgID": 7,
"admTag": {
"tagName": "Account Service Information"
}
},
{
"msgID": 6,
"admTag": {
"tagName": "Consumer Product Safety Improvement"
}
}
]
要在客户端使用此对象,我需要将结构转换为按 msgID
属性 分组,并为其分配一个包含关联 tagName
值的数组.像这样:
[{
"3": ["Employee","Safety","Performance"],
"7": ["Role Based Training","Account Service Information"],
"6": ["Consumer Product Safety Improvement"]
}]
我可以使用嵌套的 for 循环来完成此操作,但我知道使用下划线可以更有效地完成此操作,并且使用更少的代码。使用 groupBy 我能够得到一组 msgID,它为我提供了我需要的键:
_.groupBy(tags.tags, function(model){
return model.msgID;
});
...但我不确定如何从结果对象中 'pluck' tagNames 并将它们分配给正确的 msgID。
非常感谢对此的任何帮助!
简单的解决方案Javascript。只需四行代码。
var array = [{ "msgID": 3, "admTag": { "tagName": "Employee" } }, { "msgID": 3, "admTag": { "tagName": "Safety" } }, { "msgID": 3, "admTag": { "tagName": "Performance" } }, { "msgID": 7, "admTag": { "tagName": "Role Based Training" } }, { "msgID": 7, "admTag": { "tagName": "Account Service Information" } }, { "msgID": 6, "admTag": { "tagName": "Consumer Product Safety Improvement" } }],
result = {};
array.forEach(function (a) {
result[a.msgID] = result[a.msgID] || [];
result[a.msgID].push(a.admTag.tagName);
});
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
使用来自下划线的 _.reduce
var result = _.reduce(tags.tags, function(l, r) {
if (typeof l[r.msgID] === "undefined") {
l[r.msgID] = [];
}
l[r.msgID].push(r.admTag.tagName);
return l;
}, {});
使用几乎相同的代码
,本机 Array.prototype.reduce
也可以实现同样的效果
var result = tags.tags.reduce(function(l, r) {
if (typeof l[r.msgID] === "undefined") {
l[r.msgID] = [];
}
l[r.msgID].push(r.admTag.tagName);
return l;
}, {});
使用 .groupBy, .mapValues and _.map 你可以这样做:
var output = _(input)
.groupBy('msgID') // Group by msgId
.mapValues(function(group) { // Transform value of each group
return _.map(group, 'admTag.tagName'); // Return array of tagNames
})
.value();
从我的服务器 API,我请求一个具有以下结构的 javascript 对象:
[
{
"msgID": 3,
"admTag": {
"tagName": "Employee"
}
},
{
"msgID": 3,
"admTag": {
"tagName": "Safety"
}
},
{
"msgID": 3,
"admTag": {
"tagName": "Performance"
}
},
{
"msgID": 7,
"admTag": {
"tagName": "Role Based Training"
}
},
{
"msgID": 7,
"admTag": {
"tagName": "Account Service Information"
}
},
{
"msgID": 6,
"admTag": {
"tagName": "Consumer Product Safety Improvement"
}
}
]
要在客户端使用此对象,我需要将结构转换为按 msgID
属性 分组,并为其分配一个包含关联 tagName
值的数组.像这样:
[{
"3": ["Employee","Safety","Performance"],
"7": ["Role Based Training","Account Service Information"],
"6": ["Consumer Product Safety Improvement"]
}]
我可以使用嵌套的 for 循环来完成此操作,但我知道使用下划线可以更有效地完成此操作,并且使用更少的代码。使用 groupBy 我能够得到一组 msgID,它为我提供了我需要的键:
_.groupBy(tags.tags, function(model){
return model.msgID;
});
...但我不确定如何从结果对象中 'pluck' tagNames 并将它们分配给正确的 msgID。
非常感谢对此的任何帮助!
简单的解决方案Javascript。只需四行代码。
var array = [{ "msgID": 3, "admTag": { "tagName": "Employee" } }, { "msgID": 3, "admTag": { "tagName": "Safety" } }, { "msgID": 3, "admTag": { "tagName": "Performance" } }, { "msgID": 7, "admTag": { "tagName": "Role Based Training" } }, { "msgID": 7, "admTag": { "tagName": "Account Service Information" } }, { "msgID": 6, "admTag": { "tagName": "Consumer Product Safety Improvement" } }],
result = {};
array.forEach(function (a) {
result[a.msgID] = result[a.msgID] || [];
result[a.msgID].push(a.admTag.tagName);
});
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
使用来自下划线的 _.reduce
var result = _.reduce(tags.tags, function(l, r) {
if (typeof l[r.msgID] === "undefined") {
l[r.msgID] = [];
}
l[r.msgID].push(r.admTag.tagName);
return l;
}, {});
使用几乎相同的代码
,本机Array.prototype.reduce
也可以实现同样的效果
var result = tags.tags.reduce(function(l, r) {
if (typeof l[r.msgID] === "undefined") {
l[r.msgID] = [];
}
l[r.msgID].push(r.admTag.tagName);
return l;
}, {});
使用 .groupBy, .mapValues and _.map 你可以这样做:
var output = _(input)
.groupBy('msgID') // Group by msgId
.mapValues(function(group) { // Transform value of each group
return _.map(group, 'admTag.tagName'); // Return array of tagNames
})
.value();