我从服务器获得了一个平坦的JSON响应。我需要将其转换为嵌套的JSON。我可以使用for循环,但我正在寻找一种更有效的方法,如果有的话。我所拥有的JSON是月度销售数据。我需要将这个平坦的响应转换为每个月的masterAgent-subAgent数据。主代理可以有多个子代理,我需要显示每个月的报告。以下是示例JSON数组:
[{"month": "Jan-2017", "agentId": "123", "areaCode": "12", "sale": "290 units", "masterAgent": null},
{"month": "Jan-2017", "agentId": "123.1", "areaCode": "121", "sale": "120 units", "masterAgent": "121"},
{"month": "Jan-2017", "agentId": "123.2", "areaCode": "122", "sale": "170 units", "masterAgent": "121"},
{"month": "Feb-2017", "agentId": "124", "areaCode": "13", "sale": "290 units", "masterAgent": null},
{"month": "Feb-2017", "agentId": "124.1", "areaCode": "131", "sale": "120 units", "masterAgent": 124},
{"month": "Feb-2017", "agentId": "124.1", "areaCode": "132", "sale": "170 units", "masterAgent": 124}]
所需的输出是:
{
"data": [{
"month": "Jan-2017",
"agentId": "123",
"sale": "290 units",
"areaCode": "12",
"subAgentData": [{
"agentId": "123.1",
"sale": "120 units",
"areaCode": "121"
}, {
"agentId": "123.2",
"sale": "170 units",
"areaCode": "122"
}]
},
{
"month": "Feb-2017",
"agentId": "124",
"sale": "290 units",
"areaCode": "13",
"subAgentData": [{
"agentId": "124.1",
"sale": "120 units",
"areaCode": "131"
}, {
"agentId": "124.2",
"sale": "170 units",
"areaCode": "132"
}]
}
]
}
实现这一目标的最佳方法是什么?
答案 0 :(得分:0)
可以使用lodash
var items = [{"month": "Jan-2017", "agentId": "123", "areaCode": "12", "sale": "290 units", "masterAgent": null},
{"month": "Jan-2017", "agentId": "123.1", "areaCode": "121", "sale": "120 units", "masterAgent": "121"},
{"month": "Jan-2017", "agentId": "123.2", "areaCode": "122", "sale": "170 units", "masterAgent": "121"},
{"month": "Feb-2017", "agentId": "124", "areaCode": "13", "sale": "290 units", "masterAgent": null},
{"month": "Feb-2017", "agentId": "124.1", "areaCode": "131", "sale": "120 units", "masterAgent": 124},
{"month": "Feb-2017", "agentId": "124.1", "areaCode": "132", "sale": "170 units", "masterAgent": 124}];
// wrap item list into lodash chain
var groupedItems = _.chain(items)
// first group reports by month field
// results will have the form { [month1]: [list1], [month2]: [list2] }
.groupBy('month')
// discard the month key and get an array of the list part only
.values()
// process the array one list of monthly reports as a time
.map(function (monthlyReports) {
// process each report in list
return monthlyReports.reduce(function (tmp, report) {
// check the masterAgent for masterAgent report
if (report.masterAgent === null) {
// map masterAgent report fields into template
tmp.month = report.month;
tmp.agentId = report.agentId;
tmp.areaCode = report.areaCode;
tmp.sale = report.sale;
} else {
// map subAgentReport fields
tmp.subAgentData.push({
agentId: report.agentId,
areaCode: report.areaCode,
sale: report.sale,
})
}
return tmp;
}, {
// initialize the template
agentId: null,
areaCode: null,
month: null,
sale: null,
subAgentData: []
})
})
// escape lodash chain and realize value
.value();
console.log(groupedItems);

<script src="https://cdn.jsdelivr.net/lodash/4/lodash.min.js"></script>
&#13;
答案 1 :(得分:0)
这是我在jsFiddle flat json array convert to recursive json tree为您服务的代码
function getNestedChildren(arr, parent) {
var out = []
for(var i in arr) {
if(arr[i].masterAgent == parent) {
var subAgentData = getNestedChildren(arr, arr[i].areaCode)
if(subAgentData.length) {
arr[i].subAgentData = subAgentData
}
out.push(arr[i])
}
}
return out
}
var flat_array = [{"month": "Jan-2017", "agentId": "123", "areaCode": "12", "sale": "290 units", "masterAgent": 0},
{"month": "Jan-2017", "agentId": "123.1", "areaCode": "121", "sale": "120 units", "masterAgent": "121"},
{"month": "Jan-2017", "agentId": "123.2", "areaCode": "122", "sale": "170 units", "masterAgent": "121"},
{"month": "Feb-2017", "agentId": "124", "areaCode": "13", "sale": "290 units", "masterAgent": 0},
{"month": "Feb-2017", "agentId": "124.1", "areaCode": "131", "sale": "120 units", "masterAgent": 124},
{"month": "Feb-2017", "agentId": "124.1", "areaCode": "132", "sale": "170 units", "masterAgent": 124}]
var nested = getNestedChildren(flat_array, 0)
console.log(nested)
对于一般用途,递归函数有:
function getNestedChildren(arr, parent) {
var out = []
for(var i in arr) {
if(arr[i].parent == parent) {
var children = getNestedChildren(arr, arr[i].id)
if(children.length) {
arr[i].children = children
}
out.push(arr[i])
}
}
return out
}