Построить дерево каталогов из объекта

1

Имея массив элементов со следующим форматом:

[ { 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'
    }
]
};

Графическое дерево

Я думал, используя рекурсию, но я все еще не смог это сделать.

Теги:
algorithm
recursion

1 ответ

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)));
  • 0
    Что произойдет, если папки не имеют номера? Имя папки будет "моя папка" или что-то еще
  • 0
    К сожалению, я работал только с предоставленным набором данных. Не стесняйтесь обновить ваш вопрос с точным вводом / выводом, и я могу приспособиться к этому.
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню