【问题标题】:Nested tree Structure Data Generation嵌套树结构数据生成
【发布时间】:2018-10-12 12:25:02
【问题描述】:

请说出我的英语和写作问题,我有一个 json 数据数组,我试图将其放入嵌套树结构但没有成功,希望有人能帮助我。 我的示例数据:

[ {
  "id" : 1,
  "name" : "Abc",
  "path" : "/",
  "type" : "folder"
}, {
  "id" : 2,
  "name" : "Xyz",
  "path" : "/Abc/",
  "type" : "folder"
}, {
  "id" : 3,
  "name" : "Pqr",
  "path" : "/Abc/Xyz/",
  "type" : "folder"
}, {
  "id" : 4,
  "name" : "Zap", 
  "path" : "/Abc/Xyz/Pqr/",
  "type" : "folder"
 },{
  "id" : 5,
  "name" : "file1", 
  "path" : "/Abc/Xyz/Pqr/",
  "type" : "file"
},{
  "id" : 6,
  "name" : "file2", 
  "path" : "/Abc/Xyz/Pqr/",
  "type" : "file"
},{
  "id" : 7,
  "name" : "file3", 
  "path" : "/Abc/Xyz/",
  "type" : "file"
},{
  "id" : 8,
  "name" : "file4", 
  "path" : "/Abc/Xyz/Pqr/Zap/",
  "type" : "file"
}

对不起,我正在使用少量大数据来正确理解,现在我想要的嵌套格式是这样的。

[{
  "id" : 1,
  "name" : "Abc",
  "path" : "/",
  "type" : "folder"
  "Children":[{
    "id" : 2,
    "name" : "Xyz",
    "path" : "/Abc/",
    "type" : "folder",
    "Children":[{
           "id" : 3,
           "name" : "Pqr",
           "path" : "/Abc/Xyz/",
           "type" : "folder",
           "Children": [{
                   "id" : 4,
                    "name" : "Zap", 
                    "path" : "/Abc/Xyz/Pqr/",
                    "type" : "folder",
                    "Children":[{
                            "id" : 8,
                             "name" : "file4", 
                              "path" : "/Abc/Xyz/Pqr/Zap/",
                             "type" : "file"
                         }]
                   },{
                    "id" : 5,
                    "name" : "file1", 
                    "path" : "/Abc/Xyz/Pqr/",
                    "type" : "file"
                   },{
                      "id" : 6,
                      "name" : "file2", 
                      "path" : "/Abc/Xyz/Pqr/",
                      "type" : "file"
             }]
         },{
           "id" : 7,
           "name" : "file3", 
           "path" : "/Abc/Xyz/", 
           "type" : "file"
      }]
 }]
 }

现在使用 lodash 的登录是这样的:datas = allData

 const dd= [];
_.forEach(datas, function(v, k) {
  let cc = {};
    if (v.type == 'folder') {

      cc['children'] = _.filter(datas, function(v1, k1) {
        if (v.path + v.name + '/' == v1.path || v1.path.startsWith(v.path + v.name + '/')) {
          return v1;
        }
      });
      cc['name'] = v.name;
      cc['type'] = v.type;
      cc['id'] = v.id;
      cc['path'] = v.path;
      dd.push(cc);
    } else {
      if (v.path == '/') {
        dd.push(cc);
      }
    }

});

但没有正确理解,我知道问题太长了,但请帮我解决这个问题。

【问题讨论】:

  • 一致知道吗?如果有的话,它总是有 id、path、name、type 和 children

标签: javascript angular loops lodash angular6


【解决方案1】:

哇!那很有趣。

const data = [ {
  "id" : 1,
  "name" : "Abc",
  "path" : "/",
  "type" : "folder"
}, {
  "id" : 2,
  "name" : "Xyz",
  "path" : "/Abc/",
  "type" : "folder"
}, {
  "id" : 3,
  "name" : "Pqr",
  "path" : "/Abc/Xyz/",
  "type" : "folder"
}, {
  "id" : 4,
  "name" : "Zap", 
  "path" : "/Abc/Xyz/Pqr/",
  "type" : "folder"
 },{
  "id" : 5,
  "name" : "file1", 
  "path" : "/Abc/Xyz/Pqr/",
  "type" : "file"
},{
  "id" : 6,
  "name" : "file2", 
  "path" : "/Abc/Xyz/Pqr/",
  "type" : "file"
},{
  "id" : 7,
  "name" : "file3", 
  "path" : "/Abc/Xyz/",
  "type" : "file"
},{
  "id" : 8,
  "name" : "file4", 
  "path" : "/Abc/Xyz/Pqr/Zap/",
  "type" : "file"
}]

const pathPartRegex = /.*?\//g;
const tree = _.reduce(data, (result, value) => {
    const pathParts = value.path.match(pathPartRegex);
    let node = result;
    let path = "";

    // Go down through tree until last path part
    const notLastPart = pathParts.splice(0, pathParts.length - 1);
    for (const pathPart of notLastPart) {
        path += pathPart;
        const existingNode = node.children 
                                ? node.children.find(item => item.path === path)
                                : node.find(item => item.path === path);
        if (existingNode) {
            node = existingNode
        } else {
            // If we need to traverse over a path that doesn't exist, just create it
            // See notes 
            const newNode = {
                path: path,
                children: []
            };

            // The root element is just an array, and doesn't have a children property
            if (node.children) {
                node.children.push(newNode);
            } else {
                node.push(newNode);
            }
            node = newNode;
        }
    }

    // Add new node
    const newNode = {
        id: value.id,
        name: value.name,
        type: value.type,
        path: value.path,
        children: []
    };

    // The root element is just an array, and doesn't have a children property
    if (node.children) {
        node.children.push(newNode);
    } else {
        node.push(newNode);
    }

    return result;
}, []);

通过 RunKit (https://npm.runkit.com/lodash) 测试


注意事项:

示例数据集没有涵盖如何处理根本没有定义“父”路径的情况:

const data = [{
  "id" : 1,
  "name" : "Abc",
  "path" : "/",
  "type" : "folder"
}, {
  "id" : 3,
  "name" : "Pqr",
  "path" : "/Abc/Xyz/",
  "type" : "folder"
}];

也不是在子节点之后定义“父”路径的情况:

const data = [{
  "id" : 1,
  "name" : "Abc",
  "path" : "/",
  "type" : "folder"
}, {
  "id" : 3,
  "name" : "Pqr",
  "path" : "/Abc/Xyz/",
  "type" : "folder"
}, {
  "id" : 2,
  "name" : "Xyz",
  "path" : "/Abc/",
  "type" : "folder"
}];

我编写的代码将处理这些,但可能会创建没有id 属性的节点。如果您需要处理此类情况,您可以预先修复输入数据或修改此代码以处理这些情况。

【讨论】:

  • 你真的是一个很好的答案,最后只有一个问题,你正在返回结果,但你没有为结果分配任何东西,而不是每次更新的方式?
  • 我还在下面分享了一个解决方案。
  • @user3458271 本质上,reduce 就是这样工作的。它以空数组的初始值(第三个参数)开始,每次迭代返回的值传递给下一个
【解决方案2】:

我也得到的答案是这样的:

const sts=_.memoize(function(){ return []; });
const result = _.filter(folderdata, function(item){
  let parentName = '';
  if(item.path != '/')parentName = item.path;
  item.children = sts(item.path+item.name+'/');
  if (item.type == 'folder') return !(parentName && sts(parentName).push(item));
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-31
    • 2017-07-13
    • 2023-04-02
    • 1970-01-01
    • 2018-04-14
    • 2014-04-27
    • 2018-03-16
    相关资源
    最近更新 更多