来自关联数组的树

时间:2017-02-07 15:40:47

标签: javascript arrays tree

有一个数组:

let docs = [      
    { "_id":"1", parent:"_", "title":"one"},
    { "_id":"2", parent:"1", "title":"two"},
    { "_id":"4", parent:"_", "title":"title"},
    { "_id":"5", parent:"4", "title":"www"},
    {"_id":"_", "name":"root" },
];

我需要离开它,这是一棵树:

{'_id':'_','name':'root','child':
    [
        {'_id':'1','parent':'_','title':'one','child':
            [
                {'_id':'2','parent':'1','title':'two','child':[]}
            ]
        },
        {'_id':'4','parent':'_','title':'title','child':
            [
                {'_id':'6','parent':'4','title':'vvv','child':[]}
            ]
        }
    ]
}

但是我的代码只有在父元素总是高于子元素的列表中才有效,并且我希望能够普遍地完成这项工作。

这是代码:

let node = {};
for (let doc of docs) {      
    doc.child = [];
    node[doc._id] = doc;

    if (typeof doc.parent === "undefined")
        tree = doc;
    else 
        node[doc.parent].child.push(doc);
}

console.log('tree->', JSON.stringify(tree)); 
codepen上的

代码: http://codepen.io/alex183/pen/OWvrPG?editors=0112

3 个答案:

答案 0 :(得分:2)

您可以使用reduce

创建递归函数

let docs = [      
    { "_id":"1", parent:"_", "title":"one"},
    { "_id":"2", parent:"1", "title":"two"},
    { "_id":"4", parent:"_", "title":"title"},
    { "_id":"5", parent:"4", "title":"www"},
    {"_id":"_", "name":"root" }
];

function makeTree(data, parent = undefined) {
  return data.reduce(function(r, e) {
    if (e.parent == parent)(e.child = makeTree(data, e._id), r.push(e))
    return r;
  }, [])
}

console.log(makeTree(docs))

答案 1 :(得分:1)

这是一个Array#reduceMap的提案。它提前对阵列进行排序。

var docs = [{ _id: "1", parent: "_", title: "one" }, { _id: "2", parent: "1", title: "two" }, { _id: "4", parent: "_", title: "title" }, { _id: "5", parent: "4", title: "www" }, { _id: "_", name: "root" }],
    order = { undefined: -2, _: -1 },
    tree = docs
        .sort((a, b) => (order[a.parent] || a.parent) - (order[b.parent] || b.parent) || a._id - b._id)
        .reduce(
            (m, a) => (
                m
                    .get(a.parent)
                    .push(Object.assign({}, a, { child: m.set(a._id, []).get(a._id) })),
                m
            ),
            new Map([[undefined, []]])
        )
        .get(undefined);

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

答案 2 :(得分:0)

快速而肮脏的方法是使用排序功能。

docs = docs.sort((a, b) => (a._id - b._id));