Страницы

Поиск по вопросам

вторник, 7 мая 2019 г.

Нужно вывести древовидную структуру многомерного массива объектов

Есть массив обьектов:
var testObject = [ { name: 'Название 1', value: 2, childnodes: [ { name: 'Название 4', value: 25, childnodes: [ { name: 'Название 9', value: 32, childnodes: [ ] }, { name: 'Название 10', value: 0, childnodes: [ { name: 'Название 11', value: 5, childnodes: [ ] }, { name: 'Название 12', value: 2267, childnodes: [ { name: 'Название 15', value: 35, childnodes: [ { name: 'Название 16', value: 55, childnodes: [ ] } ] } ] } ] } ] }, { name: 'Название 5', value: 12, childnodes: [ ] }, { name: 'Название 6', value: 45, childnodes: [ ] }, ] }, { name: 'Название 2', value: 32, }, { name: 'Название 3', value: 7, childnodes: [ { name: 'Название 7', value: 12334, childnodes: [ { name: 'Название 13', value: 122, childnodes: [ ] } ] }, { name: 'Название 8', value: 86, childnodes: [ { name: 'Название 14', value: 222, childnodes: [ ] } ] } ] } ];
Задание состоит в том чтоб с помощью знаков псевдографики вывести древовидную структуру обьекта типа:
// ├ Название 1 // │ ├ Название 4 // │ │ ├ Название 9 // │ │ └ Название 10 // │ │ ├ Название 11 // │ │ └ Название 12 // │ │ └ Название 15 // │ │ └ Название 16 // │ ├ Название 5 // │ └ Название 6 // ├ Название 2 // └ Название 3 // ├ Название 7 // │ └ Название 13 // └ Название 8 // └ Название 14
Что я "нашаманил" на данный момент:
var symbols = Array("├", "│", "└"); //массив символов в качестве префикса для значений function buildItem(item){ var сontainer = item.name+ "
"; if( item.childnodes ) { for (var i = 0; i < item.childnodes.length; i++){ if (i < item.childnodes.length-1 && item.childnodes.length!==0) container += ( symbols[0]+ buildItem(item.childnodes[i])); else container+=(symbols[2] + buildItem(item.childnodes[i])); }; container+=symbols[1]; } return container; } var content = Array(); for (var i = 0; i < testObject.length; i++) { content[i] = buildItem(testObject[i]); }; var str = content.join("
"); console.log(str);
Результат:
Название 1 ├ Название 4 ├ Название 9 │ └ Название 10 ├ Название 11 │ └ Название 12 └ Название 15 └ Название 16 │ │ │ │ │ ├ Название 5 │ └ Название 6 │ │ Название 2 Название 3 ├ Название 7 └ Название 13 │ │ └ Название 8 └ Название 14 │ │ │
Тоесть работает код не совсем так, как хотелось бы, даже не так как надо. Суть вопроса: я вроде как и ошибку понимаю, что в первом вызове функции в принципе все хорошо, но последующая рекурсия не дает желаемого результата; прошу обьясните где я ошибаюсь, буду очень благодарен


Ответ

При печати очередного узла, перед ним нужно напечать префикс, который будет содержать связи его предков с их сиблингами. Можно заметить 2 вещи:
Для всех детей одного узла префикс будет один и тот же, поэтому его можно накапливать в параметре рекурсивной процедуры; Если узел является последним ребенком, то для него линию вниз рисовать не нужно.
Получается как-то так:
function buildTree(tree, prefix) { if (typeof prefix === 'undefined') prefix = ''; var result = ''; tree.forEach(function(e, i) { var lastNode = i == tree.length - 1; result += prefix + (lastNode ? '└' : '├') + ' ' + e.name + '
'; if (e.childnodes) result += buildTree(e.childnodes, prefix + (lastNode ? ' ' : '|') + ' '); }); return result; }
Результат:
├ Название 1 | ├ Название 4 | | ├ Название 9 | | └ Название 10 | | ├ Название 11 | | └ Название 12 | | └ Название 15 | | └ Название 16 | ├ Название 5 | └ Название 6 ├ Название 2 └ Название 3 ├ Название 7 | └ Название 13 └ Название 8 └ Название 14
function buildTree(tree, prefix) { if (typeof prefix === 'undefined') prefix = ''; var result = ''; tree.forEach(function(e, i) { var lastNode = i == tree.length - 1; result += prefix + (lastNode ? '└' : '├') + ' ' + e.name + '
'; if (e.childnodes) result += buildTree(e.childnodes, prefix + (lastNode ? ' ' : '|') + ' '); }); return result; } var testObject = [{ name: 'Название 1', value: 2, childnodes: [{ name: 'Название 4', value: 25, childnodes: [{ name: 'Название 9', value: 32, childnodes: [] }, { name: 'Название 10', value: 0, childnodes: [{ name: 'Название 11', value: 5, childnodes: [] }, { name: 'Название 12', value: 2267, childnodes: [{ name: 'Название 15', value: 35, childnodes: [{ name: 'Название 16', value: 55, childnodes: [] }] }] }] }] }, { name: 'Название 5', value: 12, childnodes: [] }, { name: 'Название 6', value: 45, childnodes: [] }, ] }, { name: 'Название 2', value: 32, }, { name: 'Название 3', value: 7, childnodes: [{ name: 'Название 7', value: 12334, childnodes: [{ name: 'Название 13', value: 122, childnodes: [] }] }, { name: 'Название 8', value: 86, childnodes: [{ name: 'Название 14', value: 222, childnodes: [] }] }] }]; document.body.innerHTML = buildTree(testObject).split('
').join('
'); body { font-family: monospace; white-space: pre; }

Комментариев нет:

Отправить комментарий