Страницы

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

понедельник, 24 февраля 2020 г.

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

#javascript #ооп


Есть массив обьектов:



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+ "\n";

    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("\n");
console.log(str);




Результат: 



Название 1
├ Название 4
├ Название 9
│ └ Название 10
├ Название 11
│ └ Название 12
└ Название 15
└ Название 16
│ │ │ │ │ ├ Название 5
│ └ Название 6
│ │ 
Название 2

Название 3
├ Название 7
└ Название 13
│ │ └ Название 8
└ Название 14
│ │ │ 




Тоесть работает код не совсем так, как хотелось бы, даже не так как надо. 
Суть вопроса: я вроде как и ошибку понимаю, что в первом вызове функции в принципе
все хорошо, но последующая рекурсия не дает желаемого результата;
прошу обьясните где я ошибаюсь, буду очень благодарен
    


Ответы

Ответ 1



При печати очередного узла, перед ним нужно напечать префикс, который будет содержать связи его предков с их сиблингами. Можно заметить 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 + '\n'; 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 + '\n'; 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('\n').join('
'); body { font-family: monospace; white-space: pre; }

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

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