使用JavaScript / NodeJS将JSON平面嵌套到JSON中

时间:2017-10-23 08:00:42

标签: javascript json node.js

我从服务器获得了一个平坦的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"
            }]
        }
    ]
}

实现这一目标的最佳方法是什么?

2 个答案:

答案 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;
&#13;
&#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
 }