递归推入数组以构建树

时间:2018-09-19 10:08:37

标签: javascript tree

我正在尝试遍历API调用中的一些JSON,并对其进行重组以构建更好地格式化以达到预期用途的树。

这是API调用中的JSON示例:

var data = [{
    "id": 1, "name": "Top Node 1", "children": {
        "value": [{
            "id": 11, "name": "Second Node 1", "children": {
                "value": [{
                    "id": 112, "children": null, "name": "Third Node 1",
                },
                {
                    "id": 112, "children": null, "name": "Third Node 2",
                }]
            }
        },
        {
            "id": 13, "name": "Second Node 3", "children": {
                "value": [{
                    "id": 131, "name": "Third Node 3", "children": {
                        "value": [{
                            "id": 1311, "name": "Fourth Node 2", "children": null
                        }]
                    }
                }]
            }
        }]
    }
},
{
    "id": 2, "name": "Top Node 2", "children": null,
}]

这是理想的结果:

var data = [{
    "treename": "Top Node 1", "treeid": 1, "collapsed": false, "children": [{
        "treename": "Second Node 1", "treeid": 11, "collapsed": false, "children": [{
            "treename": "Third Node 1", "treeid": 111, "collapsed": false, "children": []
        },
        {
            "treename": "Third Node 2", "treeid": 112, "collapsed": false, "children": []
        },
        {
            "treename": "Delete", "treeid": "source113", "collapsed": false, "children": []
        }]
    }]
}]; // and so on and so on...

这是我到目前为止尝试过的:

var buildTree = function(obj){
    console.log(traverse(obj, []));
}

var traverse = function(obj, arr){
    obj.forEach((v, k) => {
        arr.push({ children: v.children != null ? traverse(v.children.value, []) : [], treename: v.name, treeid: v.id, collapsed: false });
    });
}

buildTree(data);

jsFiddle

我的方法似乎是错误的,因为数组不断被覆盖。任何有关如何正确执行此操作的想法将不胜感激:)

2 个答案:

答案 0 :(得分:1)

您可以映射新对象并​​检查是否有子级。然后也绘制孩子们的地图。

function map({ name: treename, id: treeid, collapsed = false, children }) {
    return {
        treename,
        treeid,
        collapsed,
        children: (children && children.value || []).map(map)
    };
}

var data = [{ id: 1, name: "Top Node 1", children: { value: [{ id: 11, name: "Second Node 1", children: { value: [{ id: 112, children: null, name: "Third Node 1" }, { id: 112, children: null, name: "Third Node 2" }] } }, { id: 13, name: "Second Node 3", children: { value: [{ id: 131, name: "Third Node 3", children: { value: [{ id: 1311, name: "Fourth Node 2", children: null }] } }] } }] } }, { id: 2, name: "Top Node 2", children: null }],
    result = data.map(map);

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

ES5

function map(o) {
    return {
        treename: o.name,
        treeid: o.id,
        collapsed: false,
        children: (o.children && o.children.value || []).map(map)
    };
}

var data = [{ id: 1, name: "Top Node 1", children: { value: [{ id: 11, name: "Second Node 1", children: { value: [{ id: 112, children: null, name: "Third Node 1" }, { id: 112, children: null, name: "Third Node 2" }] } }, { id: 13, name: "Second Node 3", children: { value: [{ id: 131, name: "Third Node 3", children: { value: [{ id: 1311, name: "Fourth Node 2", children: null }] } }] } }] } }, { id: 2, name: "Top Node 2", children: null }],
    result = data.map(map);

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

答案 1 :(得分:1)

我不确定collapsed的作用.....无论如何,您可以尝试以下方法:

function t(elems, acc) {
    acc = acc  || [];
    elems.forEach(function (elem) {
        acc.push({
            treename: elem.name,
            treeid: elem.id,
            collapsed: false,
            children : (elem.children && elem.children.value) ? t(elem.children.value) : null
        });
    });
    return acc;
}
//then call it just passing your data as first param, the second is an accumulation var
var transformed = t(data);
console.log(transformed)

希望有帮助。