展平分层json数据以用于表显示

时间:2018-07-29 09:33:21

标签: javascript arrays json mongodb lodash

这是树的基本结构:

{ 
    "DescId" : "1", 
    "Desc" : "Parent 1", 
    "ParentId" : "null", 
    "Order" : 1.0, 
    "Type" : "A", 
    "Parent" : null, 
    "Depth" : 0.0
}
{ 
    "DescId" : "1.1", 
    "Desc" : "Child 1", 
    "ParentId" : "1", 
    "Order" : 1.0, 
    "Type" : "B", 
    "Parent" : "Parent 1", 
    "Depth" : 1.0
}
{ 
    "DescId" : "1.2", 
    "Desc" : "Child 2", 
    "ParentId" : "1", 
    "Order" : 2.0, 
    "Type" : "B", 
    "Parent" : "Parent 1", 
    "Depth" : 1.0
}
{ 
    "DescId" : "1.1.1", 
    "Desc" : "Grand Child 1", 
    "ParentId" : "1.1", 
    "Order" : 1.0, 
    "Type" : "C", 
    "Parent" : "Child 1", 
    "Depth" : 2.0
}
{ 

    "DescId" : "1.1.1.1", 
    "Desc" : "Great Grand Child 1", 
    "ParentId" : "1.1.1", 
    "Order" : 1.0, 
    "Type" : "D", 
    "Parent" : "Grand Child 1", 
    "Depth" : 3.0
}
{ 

    "DescId" : "2", 
    "Desc" : "Parent 2", 
    "ParentId" : null, 
    "Order" : 2.0, 
    "Type" : "A", 
    "Parent" : null, 
    "Depth" : 0.0
}

我具有以下分层json数据:

[
  {
    "DescId": "1",
    "Desc": "Parent 1",
    "Type": "A",
    "children": [
      {
        "DescId": "1.2",
        "Desc": "Child 2",
        "ParentId": "1",
        "Order": 2,
        "Type": "B",
        "Parent": "Parent 1",
        "Depth": 1
      },
      {
        "DescId": "1.1",
        "Desc": "Child 1",
        "ParentId": "1",
        "Order": 1,
        "Type": "B",
        "Parent": "Parent 1",
        "Depth": 1
      }
    ]
  },
  {
    "DescId": "1.1",
    "Desc": "Child 1",
    "Type": "B",
    "children": [
      {
        "DescId": "1.1.1",
        "Desc": "Grand Child 1",
        "ParentId": "1.1",
        "Order": 1,
        "Type": "C",
        "Parent": "Child 1",
        "Depth": 2
      }
    ]
  },
  {
    "DescId": "1.2",
    "Desc": "Child 2",
    "Type": "B",
    "children": []
  },
  {
    "DescId": "1.1.1",
    "Desc": "Grand Child 1",
    "Type": "Consequence",
    "children": [
      {
        "DescId": "1.1.1.1",
        "Desc": "Great Grand Child 1",
        "ParentId": "1.1.1",
        "Order": 1.0,
        "Type": "D",
        "Parent": "Grand Child 1",
        "Depth": 3.0
      }
    ]
  },
  {
    "DescId": "1.1.1.1",
    "Desc": "Great Grand Child 1",
    "Type": "D",
    "children": []
  },
  {
    "DescId": "2",
    "Desc": "Parent 2",
    "Type": "A",
    "children": []
  }
]

我有这个要求,我需要将此分层树显示为表格结构。

因此数据需要如下所示:

[
  {
    "A" + "DescId" : "1",
    "A" + "Desc" : "Parent",
    "B" + "DescId" : "1.1",
    "B" + "Desc" : "Child 1,
    "C" + "DescId" : "1.1.1",
    "C" + "Desc" : "Grand Child 1"
    "D" + "DescId" : "1.1.1.1",
    "D" + "Desc" : "Great Grand child 1"
  },
  {
    "A" + "DescId" : "1",
    "A" + "Desc" : "Parent 1",
    "B" + "DescId" : "1.2"
    "B" + "Desc" : "Child 2
    //if there are any further generations like 1.2.1 or 1.2.1.1 should be present here
  },
  {
    "A" + "DescId" : "2",
    "A" + "Desc" : "Parent 2"
  }
]

我已经在javascript和lodash中尝试了以下代码:

function reformatData(sentData) {
        var finalData = {};
        var returnArray = [];
        if (sentData.length > 0) {
            var propertyNameArray = Object.keys(sentData[0]);

            for (var i = 0; i < sentData.length; i++) {
                var type = sentData[i].Type;
                finalData[type + propertyNameArray[0]] = sentData[i].DescId;
                finalData[type + propertyNameArray[1]] = sentData[i].Desc;
                if (sentData[i].children && sentData[i].children.length > 0) {
                    var children = _.orderBy(sentData[i].children, ['Order'], ['asc']);
                    reformatData(children);
                }
            }
        }
        returnArray.push(finalData);
        return returnArray;
    }

上面的代码忽略第一个父级,仅添加下一个可用父级。谁能帮助我指出我在这里所缺少的。下面是生成的输出代码:

[
  {
    "ADescid":"2",
    "ADesc":"Parent 2",
    "BDescid":"1.2",
    "BDesc":"Child 2",
    "CDescid":"1.1.1",
    "CDesc":"Grand Child 1",
    "DDescid":"1.1.1.1",
    "DDesc":"Great grand child 1"
  }
]

2 个答案:

答案 0 :(得分:2)

这可以通过递归生成器函数以非常优雅的方式解决:

 function* paths(node, parent = {}) {
   const current = {
     ...parent,
     [node.type + "DescId"]: node.DescId,
     [node.type + "Desc"]: node.Desc,
   };

   if(node.children && node.children.length) {
     for(const child of node.children)
        yield* paths(child, current);
   } else {
     yield current;
   }
}

// The following is only needed as your root is an array not a node
function* pathArray(array) {
  for(const el of array) yield* paths(el);
}

因此您可以将其称为:

const result = [...pathArray(yourTreeArray)];

答案 1 :(得分:2)

此提案分三个步骤进行:

  1. 建造树。
  2. 将所有节点收集到最终叶子。
  3. 生成具有所需键作为最终结果的单个对象。

function getTree(array, root) {
    var o = {};
    array.forEach(function (a) {
        o[a.DescId] = Object.assign({}, a, o[a.DescId]);
        o[a.ParentId] = o[a.ParentId] || {};
        o[a.ParentId].children = o[a.ParentId].children || [];
        o[a.ParentId].children.push(o[a.DescId]);
    });
    return o[root].children;
}

function getLeafes(tree) {
    var result = [];
    tree.forEach(function iter(temp) {
        return function ({ DescId, Desc, Type, children }) {
            var t = temp.concat({ DescId, Desc, Type });
            if (!children) {
                result.push(t);
                return;
            }
            children.forEach(iter(t));
        };
    }([]));
    return result;
}

var nodes = [{ DescId: "1", Desc: "Parent 1", ParentId: "null", Order: 1, Type: "A", Parent: null, Depth: 0 }, { DescId: "1.1", Desc: "Child 1", ParentId: "1", Order: 1, Type: "B", Parent: "Parent 1", Depth: 1 }, { DescId: "1.2", Desc: "Child 2", ParentId: "1", Order: 2, Type: "B", Parent: "Parent 1", Depth: 1 }, { DescId: "1.1.1", Desc: "Grand Child 1", ParentId: "1.1", Order: 1, Type: "C", Parent: "Child 1", Depth: 2 }, { DescId: "1.1.1.1", Desc: "Great Grand Child 1", ParentId: "1.1.1", Order: 1, Type: "D", Parent: "Grand Child 1", Depth: 3 }, { DescId: "2", Desc: "Parent 2", ParentId: null, Order: 2, Type: "A", Parent: null, Depth: 0 }],
    tree = getTree(nodes, null),
    leaves = getLeafes(tree),
    result = leaves.map(a => a.reduce((o, { DescId, Desc, Type }) => Object.assign(o, { [Type + 'DescId']: DescId, [Type + 'Desc']: Desc }), {}));

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