Есть массив обьектов:
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;
}