文件路径字符串数组到文件树JSON(与react-sortable-tree兼容)

时间:2017-07-07 17:43:10

标签: javascript json reactjs tree filetree

如何构建一个与react-sortable-tree兼容的JSON对象(每个嵌套对象都有title,children)来呈现文件树。

例如,我有这个文件路径数组。

var filePaths = [
   "Diagnoses/Endocrine disorders/Thyroid disorders/Congenital hypothyroidism",
   "Diagnoses/Endocrine disorders/Thyroid disorders/Acquired hypothyroidism",
   "Diagnoses/Endocrine disorders/Thyroid disorders/Acquired hypothyroidism/Postsurgical hypothyroidism"
];

我想要一个像这样的JSON对象。

var treeData = [
  {
    title: 'Diagnoses',
    children: [{
      title: 'Endocrine disorders',
      children: [{
        title: 'Thyroid disorders',
        children: [
        {
          title: 'Congential hypothyroidism'
        },
        {
          title: 'Acquired hypothyroidism',
          children: [{
            title: 'Postsurgical hypothyroidism'
          }]
        }
        ]
      }]
    }]
  }
];

编辑:我尝试了这个但是在第一次迭代之后,我覆盖了整棵树的children属性。我尝试了几项检查来阻止它,但它们并没有完全消失。

var hierarchy = filePaths.reduce(function(hier,path){
    var x = hier;
    path.split('/').forEach(function(item, index, array){
        if(x[0].title != item){
            x[0].title = item;
        }
        // console.log(index, array.length)
        if (index != array.length - 1 && !x[0].children){
          x[0].children = [{
            title: ''
          }];
        }
        x = x[0].children;
    });

    return hier;
}, [{title: ''}]);

1 个答案:

答案 0 :(得分:2)

我认为您的代码的主要问题是您没有走在树下以在正确的位置插入节点。

我采取了两步法,因为我不喜欢每次字典查找更快时迭代孩子列表的想法。

请参阅代码中的注释,了解正在进行的操作:



var filePaths = [
  "Diagnoses/Endocrine disorders/Thyroid disorders/Congenital hypothyroidism",
  "Diagnoses/Endocrine disorders/Thyroid disorders/Acquired hypothyroidism",
  "Diagnoses/Endocrine disorders/Thyroid disorders/Acquired hypothyroidism/Postsurgical hypothyroidism"
];

// Step 1:
// Convert the flat list of paths to nested dictionaries.
// (This representation is more efficient for the initial construction.)
// Basic algorithm:
// 1. Split each path into segments.
// 2. Walk down the tree using the segments as keys.
// 3. Create new nodes as necessary.

var tree = {};
filePaths.forEach(function (path) {
  var currentNode = tree;
  path.split('/').forEach(function (segment) {
    if (currentNode[segment] === undefined) {
      currentNode[segment] = {};
    }
    currentNode = currentNode[segment];
  });
});

// Now we have a tree represented as nested dictionaries.
console.log(JSON.stringify(tree, null, 2));

// {
//   "Diagnoses": {
//     "Endocrine disorders": {
//       "Thyroid disorders": {
//         "Congenital hypothyroidism": {},
//         "Acquired hypothyroidism": {
//           "Postsurgical hypothyroidism": {}
//         }
//       }
//     }
//   }
// }

// Step 2:
// Convert the nested dictionaries into lists of children.
// This is the format required for react-sortable-tree.
// Basic algorithm:
// 1. Each dictionary becomes an array of children.
// 2. Each element of the array has a title and a list of children.
// 3. We recurse for the list of children (if we have children).
function toTreeData(tree) {
  return Object.keys(tree).map(function (title) {
    var o = { title: title };
    if (Object.keys(tree[title]).length > 0) {
      o.children = toTreeData(tree[title]);
    }

    return o;
  });
}

console.log(JSON.stringify(toTreeData(tree), null, 2));

// [
//   {
//     "title": "Diagnoses",
//     "children": [
//       {
//         "title": "Endocrine disorders",
//         "children": [
//           {
//             "title": "Thyroid disorders",
//             "children": [
//               {
//                 "title": "Congenital hypothyroidism"
//               },
//               {
//                 "title": "Acquired hypothyroidism",
//                 "children": [
//                   {
//                     "title": "Postsurgical hypothyroidism"
//                   }
//                 ]
//               }
//             ]
//           }
//         ]
//       }
//     ]
//   }
// ]