I have a flat JSON response from server. I need to convert it to nested JSON. I can do that using for loop but I am looking for a more efficient way if there is one. The JSON I have is for monthly sales figures. I need to convert this flat response to masterAgent-subAgent data for each month. A master agent can have multiple sub agents and I need to show thee report for each month. Here is the sample JSON array:
[{"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}]
The desired output is:
{
"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"
}]
}
]
}
What is the best way to achieve this?
This could easily be done using 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>
here is my working code for you at 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)
For general use, recursive function are:
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
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.