从对象构建目录树

时间:2018-09-25 02:41:38

标签: javascript algorithm recursion

具有以下格式的项目数组:

[ { path: '/Folder 1/Folder 1.1',
    name: 'Folder 1.1.1',
    id: 'Fi6CsP4RWFutOZKsIDoYMSfBPQb-A-lj3C4Jc_zZoG0' },
  { path: '/Folder 1',
    name: 'Folder 1.2',
    id: 'c2dTN3CgBr9Xik8jdpBkfzR6wZ00oGTX3IbfXrfFujM' },
  { path: '/Folder 1',
    name: 'Folder 1.1',
    id: 'WmKaOZhzpubcunNNoxbUnqfSYVuNQZDNC852KDJK_G8' },
  { path: '/',
    name: 'Folder 1',
    id: 'aNRvIvCLyNOgLOmZVzFhoOiZMAz3-p87kBFIGSQS2Yg' },
  { path: '/',
    name: 'Folder 2',
    id: 'S4FkkQ3hgLTVedIrlSBqe2_1DhrrnLx5szk7-9Wv3X8' } ]

可以采用以下格式

var dir = {
"directory": [{
        "text": "Folder 1",
        "id": 'aNRvIvCLyNOgLOmZVzFhoOiZMAz3-p87kBFIGSQS2Yg',
        "nodes": [{
            "text": "Folder 1.1",
            "id": 'WmKaOZhzpubcunNNoxbUnqfSYVuNQZDNC852KDJK_G8',
            "nodes": [{
                "text": "Folder 1.1.1",
                "id": 'Fi6CsP4RWFutOZKsIDoYMSfBPQb-A-lj3C4Jc_zZoG0'
            }]
            }, {
            "text": "Folder 1.2",
            "id": 'c2dTN3CgBr9Xik8jdpBkfzR6wZ00oGTX3IbfXrfFujM'
        }]
    },
    {
        "text": "Folder 2",
        "id": 'S4FkkQ3hgLTVedIrlSBqe2_1DhrrnLx5szk7-9Wv3X8'
    }
]
};

以图形方式 Tree

我当时在考虑使用递归,但是我仍然无法做到这一点。

1 个答案:

答案 0 :(得分:2)

这是一种非递归解决方案,其工作原理是先构建一棵树,然后将树转换为所需的结构。

第一步的原因是由于在线性时间内对node个数组进行迭代的速度很慢,并且不考虑平面输入数组的顺序。在对象树结构上执行查找可以加快并简化过程,从而使结果树易于在单个遍历中构建。

const treeify = data => 
  data.reduce((a, e) => {
    let level = a;
    
    e.path.split("/")
      .filter(e => e)
      .forEach(dir => {
        if (!(dir in level)) {
          level[dir] = {nodes: {}};
        }

        level = level[dir].nodes;
      })
    ;
    
    if (e.name in level) {
      level[e.name] = {
        text: e.name,
        id: e.id, 
        nodes: level[e.name].nodes
      };
    }
    else {
      level[e.name] = {text: e.name, id: e.id};
    }
    
    return a;
  }, {})
;

const format = tree => {
  const result = [];
  const stack = [[result, tree]];
  
  while (stack.length) {
    const [res, curr] = stack.pop();
    
    for (const k in curr) {
      const o = {
        id: curr[k].id,
        text: curr[k].text
      };
      res.push(o);
      
      if (curr[k].nodes) {
        o.nodes = [];
        stack.push([o.nodes, curr[k].nodes]);
      }
    }
  }
  
  return {directory: result};
};

const data = [
  {
    path: '/Folder 1/Folder 1.1',
    name: 'Folder 1.1.1',
    id: 'Fi6CsP4RWFutOZKsIDoYMSfBPQb-A-lj3C4Jc_zZoG0'
  },
  {
    path: '/Folder 1',
    name: 'Folder 1.2',
    id: 'c2dTN3CgBr9Xik8jdpBkfzR6wZ00oGTX3IbfXrfFujM'
  },
  {
    path: '/Folder 1',
    name: 'Folder 1.1',
    id: 'WmKaOZhzpubcunNNoxbUnqfSYVuNQZDNC852KDJK_G8'
  },
  {
    path: '/',
    name: 'Folder 1',
    id: 'aNRvIvCLyNOgLOmZVzFhoOiZMAz3-p87kBFIGSQS2Yg'
  },
  {
    path: '/',
    name: 'Folder 2',
    id: 'S4FkkQ3hgLTVedIrlSBqe2_1DhrrnLx5szk7-9Wv3X8'
  }
];

console.log(format(treeify(data)));