我有一个小型的Web应用程序,该应用程序使用API调用来获取数据,响应是一系列报告,每个报告都有唯一的ID,应用程序,类型和标题。
我想通过按应用程序分组然后按类型将其映射到新对象中 如下所述。
[
{
"id": "REPORT1",
"application": "APP1",
"type": "TYPE1",
"title": ""
},
{
"id": "REPORT2",
"application": "APP1",
"type": "TYPE1",
"title": ""
},
{
"id": "REPORT3",
"application": "APP1",
"type": "TYPE2",
"title": ""
},
{
"id": "REPORT4",
"application": "APP2",
"type": "TYPE3",
"title": ""
}
]
{
"APP1": {
"TYPE1": [
{
"id": "REPORT1",
"application": "APP1",
"type": "TYPE1",
"title": ""
},
{
"id": "REPORT2",
"application": "APP1",
"type": "TYPE1",
"title": ""
}
],
"TYPE2": [
{
"id": "REPORT3",
"application": "APP1",
"type": "TYPE2",
"title": ""
}
]
},
"APP2": {
"TYPE3": [
{
"id": "REPORT4",
"application": "APP2",
"type": "TYPE3",
"title": ""
}
]
}
}
有了loadash
,我想到了这一点:
const output = _(input)
.groupBy(report => report.application)
.value()
按application
分组后,我需要按type
进行另一个嵌套分组或映射,但是卡住了。
答案 0 :(得分:5)
这很容易实现,无需通过the Array#reduce()
function进行破折号。
有关如何实现此目的的详细信息,请参见代码段源代码中的注释:
var input = [{
"id": "REPORT1",
"application": "APP1",
"type": "TYPE1",
"title": ""
},
{
"id": "REPORT2",
"application": "APP1",
"type": "TYPE1",
"title": ""
},
{
"id": "REPORT3",
"application": "APP1",
"type": "TYPE2",
"title": ""
},
{
"id": "REPORT4",
"application": "APP2",
"type": "TYPE3",
"title": ""
}
];
var output = input.reduce((result, item) => {
// Get app object corresponding to current item from result (or insert if not present)
var app = result[item.application] = result[item.application] || {};
// Get type array corresponding to current item from app object (or insert if not present)
var type = app[item.type] = app[item.type] || [];
// Add current item to current type array
type.push(item);
// Return the result object for this iteration
return result;
}, {});
console.log(output);
.as-console-wrapper {
height:100% !important;
max-height:unset !important;
}
答案 1 :(得分:2)
您可以采用动态方法对想要的键进行分组。
groups = ["application", "type"]
然后减少数据数组和键数组,并根据需要构建新对象,或者与最后一组一起构建用于推送实际对象的数组。
如有必要,可以轻松地将此解决方案扩展到更多的嵌套组。
var data = [{ id: "REPORT1", application: "APP1", type: "TYPE1", title: "" }, { id: "REPORT2", application: "APP1", type: "TYPE1", title: "" }, { id: "REPORT3", application: "APP1", type: "TYPE2", title: "" }, { id: "REPORT4", application: "APP2", type: "TYPE3", title: "" }],
groups = ["application", "type"],
grouped = data.reduce((r, o) => {
groups
.reduce((group, key, i, { length }) =>
group[o[key]] = group[o[key]] || (i + 1 === length ? [] : {}), r)
.push(o);
return r;
}, {});
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 2 :(得分:2)
es6,对象的扩散和缩小使其变得更加简单
const input = [
{
"id": "REPORT1",
"application": "APP1",
"type": "TYPE1",
"title": ""
},
{
"id": "REPORT2",
"application": "APP1",
"type": "TYPE1",
"title": ""
},
{
"id": "REPORT3",
"application": "APP1",
"type": "TYPE2",
"title": ""
},
{
"id": "REPORT4",
"application": "APP2",
"type": "TYPE3",
"title": ""
}
]
const output = input.reduce((acc, item) => ({
...acc,
[item.application]: {
...acc[item.application],
[item.type]: [
...(acc[item.application] && acc[item.application][item.type] || []),
item,
]
}
}), {})
console.log(output)
答案 3 :(得分:0)
我个人发现在 Lodash 中结合 _.groupBy 和 _.mapValues 时这更易读:
var input = [{ id: "REPORT1", application: "APP1", type: "TYPE1", title: "" }, { id: "REPORT2", application: "APP1", type: "TYPE1", title: "" }, { id: "REPORT3", application: "APP1", type: "TYPE2", title: "" }, { id: "REPORT4", application: "APP2", type: "TYPE3", title: "" }]
const output = _.mapValues(_.groupBy(input, i => i.application),app => _.groupBy(app, i => i.type))
console.log(output)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>