在给定 parent id 和 children 的情况下,在 lodash 中嵌套 parent child 关系

Nesting a parent child relationship in lodash, given the parent id and children

如果 parent 及其 children 作为 属性.[=17=,我将如何嵌套 json object ]

数据看起来像:

   "1": {
        "id": 1,
        "name": "foo",
        "parent": null,
        "root": 1,
        "children": [2, 4, 6],
        "posts":[
            { "id": "1", "name": "item1" },
            { "id": "2", "name": "item2" },
            { "id": "3", "name": "item3" }
        ]
    },
    "2": {
        "id": 2,
        "name": "bar",
        "parent": 1,
        "root": 1,
        "children": null,
        "posts":[
            { "id": "4", "name": "item4" }
        ]
    },
    "3": {
        "id": 3,
        "name": "bazz",
        "parent": null,
        "root": 3,
        "children": [5, 7],
        "posts":[
            { "id": "5", "name": "item5" },
            { "id": "6", "name": "item6" }
        ]
    },
   ....

一个简单的 groupby 使用 lodash 是行不通的。

var group = _.groupBy(data, 'parent');

这是一个fiddle:

http://jsfiddle.net/tzugzo8a/1/

问题的上下文是一个带有子类别的嵌套类别,类别中可以包含类别和帖子。

基本上我不想为 children 和帖子设置不同的 属性,因为它们都是 parent 的 children。

期望输出

    "1": {
        "id": 1,
        "name": "foo",
        "parent": null,
        "root": 1,
        "isCategory": true,
        "children": [
             {
                 "id": 2,
                 "name": "bar",
                 "parent": 1,
                 "root": 1,
                 "isCategory": true,
                 "children": null
             },
             { "id": "1", "name": "item1", isCategory: false },
             { "id": "2", "name": "item2", isCategory: false },
             { "id": "3", "name": "item3", isCategory: false }

        ]
        ...
    }

看看更新后的 fiddle:

var data = getData();

_.keys(data).forEach(function(id){
    var element = data[id];
    if (element.children === null){
        element.children = [];
    }

    element.isCategory = true;
    element.items.forEach(function(item){
        item.isCategory = false;
    })
});

_.keys(data).forEach(function(id){
    var element = data[id];
    element.children = element.children.map(function(childId){
      return data[childId];
    }).concat(element.items);
});

_.keys(data).forEach(function(id){
    delete data[id].items;
});

console.log(JSON.stringify(_.findWhere(_.values(data), {'parent': null})));

这是我对这个问题的看法 (fiddle):

var data = getData();

var group = getTree(data);

console.log(group);

function getTree(flat) {
    return _.reduce(flat, function (treeObj, item, prop, flatTree) {
        var children = _.map(item.children, function (childId) {
            return _.set(flatTree[childId], 'isCategory', true);
        }).concat(_.map(item.items, function(item) {
            return _.set(item, 'isCategory', false);
        }));

        item.children = !!children.length ? children : null;

        delete item.items;

        item.parent === null && (treeObj[prop] = item);

        return treeObj;
    }, {});
}