首页 > 解决方案 > 格式化 JSON 以形成分组数组

问题描述

我有需要格式化和汇总以进行分组的数据。

sourceData ==>

var obj = 
  [
    {
    "level1": "A1",
    "level2":"B1",
    "level3":"C1",
    "amount":165
  },
          {
    "level1": "A1",
    "level2":"B1",
    "level3":"D1",
    "amount":156
  },

      {
    "level1": "A1",
    "level2":"B2",
    "level3":"C2",
    "amount":145
  },

    {
    "level1": "A1",
    "level2":"B2",
    "level3":"D2",
    "amount":110
  }]

现在我希望对数据进行分组,以便可以在每个级别上计算总金额,它应该如下所示:

  var Obj = [
      {
    "level1": "A1",
    "amount":576,
    "child":[{
      "level2":"B1",
      "amount":231,
      "child":[{
         "level3":"C1", "amount":165},
         {"level3":"D1", "amount":156}
        ]
    },{
       "level2":"B2",
       "amount":255,
      "child":[
        {"level3":"C2", "amount":145},
         {"level3":"D2", "amount":110}
        ]


    }]
  }
  ]

尽管我创建了作为循环有效工作的代码,但我无法添加数量并对其进行总结。

 keys = ['level1', 'level2', 'level3'],
    result = data.reduce((r, o) => (
        keys.reduce((level, k) => {
            var temp = (level.child = level.child || []).find(p => o[k] === p[k]);
            if (!temp) {
                level.child.push(temp = { [k]: o[k] });
            }
            return temp;
        }, r),
        r
    ), { child: [] }).child;

console.log(result);

标签: javascriptarraysjson

解决方案


您可以为外部键使用辅助数组,以正确的顺序对其进行迭代,并通过对任意嵌套数据结构采用嵌套方法并查找结果数组的每一级来减少数组。

如果在实际关卡中没有找到key,则生成一个新对象并返回子数组进行下一层搜索。

要将具有所需键的对象推送到最内部的孩子,您可以通过省略使用的键并仅获取剩余的键和值来创建一个新对象。

继续直到迭代数据数组的所有对象。

结果是child在离开对象中没有数组的嵌套结构。

让您可以通过迭代数组及其子对象来计算每个对象的数量。

function calculateAmount(array) {
    return array.reduce((s, o) => {
        if (!('amount' in o)) {
            o.amount = calculateAmount(o.child);
        }
        return s + o.amount;
     }, 0);
}

var data = [{ level1: "A1", level2: "B1", level3: "C1", amount: 165 }, { level1: "A1", level2: "B1", level3: "D1", amount: 156 }, { level1: "A1", level2: "B2", level3: "C2", amount: 145 }, { level1: "A1", level2: "B2", level3: "D2", amount: 110 }],
    keys = ['level1', 'level2'],
    result = data.reduce((r, o) => (
        keys
            .reduce((level, k) => {
                var temp = level.find(p => o[k] === p[k]);
                if (!temp) {
                    level.push(temp = { [k]: o[k], child: [] });
                }
                return temp.child;
            }, r)
            .push(Object.assign(
                ...Object.keys(o).map(k => keys.includes(k) || { [k]: o[k] })
            )),
        r
    ), []);

calculateAmount(result);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }


推荐阅读