【问题标题】:Dynamic index structure load translating to Array when calling a json调用json时动态索引结构加载转换为数组
【发布时间】:2020-03-07 09:23:13
【问题描述】:

我有这样的文件结构:

{
  "hierarchy": [
    {
      "type": "folder",
      "name": "src",
      "child": [
        {
          "type": "folder",
          "name": "assets",
          "child": [
            {
              "type": "folder",
              "name": "styles",
              "child": [
                {
                  "type": "file",
                  "name": "style.css",
                  "data": "style"
                }
              ]
            },
            {
              "type": "folder",
              "name": "scripts",
              "child": [
                {
                  "type": "file",
                  "name": "script.js",
                  "data": "script"
                }
              ]
            }
          ]
        },
        {
          "type": "file",
          "name": "index.html",
          "data": "html"
        },
        {
          "type": "file",
          "name": "manifest.json",
          "data": "manifest"
        }
      ]
    },
    {
      "type": "folder",
      "name": "dist",
      "child": []
    }
  ]
}

监听这个根目录和所有子目录,创建一个镜像这个目录结构的Array,每个节点包含类型、名称、路径和子节点:

[
    ["folder","src","./"],
    ["file","index.html","./src/"],         
    ["file","index.html","./src/"],
    ["folder","assets","./src/"],
    ["folder","styles","./src/assets/"],
    ["folder","scripts","./src/assets/"],
    ["file","style.css","./src/assets/styles/"],
    ["file","script.js","./src/assets/scripts/"],
    ["folder","dist","./"]
]

我想动态监听 JSON 文件并创建一个数组,如示例所示。

【问题讨论】:

  • @rule 我没有尝试任何合适的方法。它没有用。
  • 为什么最后一个文件夹有"child": [null]?不应该是"child": [ ]

标签: javascript arrays json type-conversion


【解决方案1】:

您可以采用递归方法并迭代给定的树。

function getFlat(array, path = './') {
    return array.reduce((r, { type, name, child = [] }) => {
        r.push([type, name, path], ...getFlat(child, `${path}${name}/`));
        return r;
    }, []);
}

var tree = { hierarchy: [{ type: "folder", name: "src", child: [{ type: "folder", name: "assets", child: [{ type: "folder", name: "styles", child: [{ type: "file", name: "style.css", data: "style" }] }, { type: "folder", name: "scripts", child: [{ type: "file", name: "script.js", data: "script" }] }] }, { type: "file", name: "index.html", data: "html" }, { type: "file", name: "manifest.json", data: "manifest" }] }, { type: "folder", name: "dist", child: [] }] },
    result = getFlat(tree.hierarchy);    

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

【讨论】:

    【解决方案2】:

    您可以像这样递归地实现这一点:

    function getEntriesFromHierarchy(hierarchy, path, entries = []) {
        entries.push([ hierarchy.type, hierarchy.name, path ]);
    
        if(hierarchy.type === "folder") {
            hierarchy.child.forEach(childHierarchy =>
                getEntriesFromHierarchy(childHierarchy, path + hierarchy.name + "/", entries)
            );
        }
    
        return entries;
    }
    
    let results = yourObject.hierarchy.reduce((acc, hierarchy) => 
        acc.concat(getEntriesFromHierarchy(hierarchy, "./"))
    , []);
    

    getEntriesFromHierarchy 将层次结构对象对应的条目添加到数组entries 中,如果层次结构是文件夹,它会在该文件夹的每个子层次结构上调用自身。它传递数组entries,以便可以使用它而不是每次都创建一个新数组,因此层次结构中的所有文件都包含在同一个数组中。

    由于您的对象hierarchy 属性是一个层次结构数组,我们使用reduce 将所有结果数组连接到results 数组中。对数组hierarchy 中的层次结构的每次调用getEntriesFromHierarchy 都会返回一个与该特定层次结构相对应的结果数组,因此我们需要将所有这些数组合并为一个,这就是代码的第二部分负责的内容。

    【讨论】:

    • 非常感谢。我完全明白了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    • 1970-01-01
    • 1970-01-01
    • 2021-02-14
    相关资源
    最近更新 更多