基于JSON对象数组创建嵌套JSON

时间:2017-06-01 13:14:30

标签: javascript json

我有一个JSON对象数组,类似于:

var fileArray = [
  { name: "file1", path: "/main/file1" },
  { name: "file2", path: "/main/folder2/file2" },
  { name: "file4", path: "/main/folder3/file4" },
  { name: "file5", path: "/main/file5" },
  { name: "file6", path: "/main/file6" }
];  

我希望它最终看起来像是:

fileTree = [
  {
    "name": "file1",
    "children": []
  },
  {
    "name": "folder1"
    "children": [
      {
        "name": "folder2",
        "children": [
          {
            "name": "file2",
            "children": []
          }
        ]
      },
      {
        "name": "folder3",
        "children": [
          {
            "name": "file4",
            "children": []
                }
              ]
            }
          ]
        },
  {
    "name": "file5",
    "children": []
        },
  {
    "name": "file6",
    "children": []
  }
];

我尝试了Create a nested UL menu based on the URL path structure of menu items中提到的解决方案,但对第一个答案的第一个评论正是我遇到的问题。感谢所有帮助。

2 个答案:

答案 0 :(得分:1)

您可以使用嵌套哈希表作为对相同目录的引用,并以与结果集相同的方式构建。

var fileArray = [{ name: "file1", path: "/main/file1" }, { name: "file2", path: "/main/folder2/file2" }, { name: "file4", path: "/main/folder3/file4" }, { name: "file5", path: "/main/file5" }, { name: "file6", path: "/main/file6" }],
    temp = [],
    fileTree;

fileArray.forEach(function (hash) {
    return function (a) {
        a.path.replace('/', '').split('/').reduce(function (r, k) {
            if (!r[k]) {
                r[k] = { _: [] };
                r._.push({ name: k, children: r[k]._ });
            }
            return r[k];
        }, hash);
    };
}({ _: temp }));

fileTree = temp[0].children;
console.log(fileTree);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:0)

这不会给出你想要的确切结果,但我认为它是可用的:

var fileArray = [
  { name: "file1", path: "/main/file1" },
  { name: "file2", path: "/main/folder2/file2" },
  { name: "file4", path: "/main/folder3/file4" },
  { name: "file5", path: "/main/file5" },
  { name: "file6", path: "/main/file6" }
];  

var tree = fileArray.reduce(function (b, e) {
  var pathbits = e.path.split("/");
  var r = b;
  for (var i=1; i < pathbits.length - 1; i++) {
    bit = pathbits[i];
    if (!r[bit]) r[bit] = {};
    r = r[bit];
  }
  if (!r.files) r.files = [];
  r.files.push(e.name);
  return b;
}, {});

console.log(tree);