#javascript
#javascript
Вопрос:
У меня есть массив объектов, которые представляют структуру разметки HTML-страницы. Я написал рекурсивную функцию, которая частично работает, но не может понять, как вернуть более одного дочернего объекта из объекта, имеющего более одного дочернего объекта.
Вот массив объектов:
const arrayOfObjects = [
{"type": "Root", "id":0, "children" : [
{"type" : "Title", "id": "foo"},
{"type" : "Image", "id": "bar"},
{"type" : "Container", "id": "blo", "children":[
{"type" : "Container", "id": "goo", "children":[
{"type" : "Image", "id": "tar"},
{"type" : "Video", "id": "yar"}
]},
{"type" : "Container", "id": "sha", "children":[
{"type" : "Title", "id": "koo"},
]},
]},
{"type" : "Container", "id": "boo", "children":[
{"type" : "Container", "id": "bos", "children":[
{"type" : "Container", "id": "ooo", "children":[
{"type" : "Container", "id": "loo", "children":[
{"type" : "Title", "id": "bar"},
{"type" : "Image", "id": "rab"}
]}
]}
]}
]}
]}
]
Вот мой код:
const findChildren = (el) => {
let x = []
if(el.type === "Container"){
x = '[' el.type ']'
findChildren(el.children[0])
'[/' el.type ']'
return x
}
else{
return x = '[' el.type '/]'
}
}
genStructure = (data) => {
let output = []
data.forEach(function(el) {
output = findChildren(el)
});
return output
}
genStructure(arrayOfObjects[0].children) // here I ignore root as it will always be the same
Это то, что я получаю, когда запускаю его.
[Title/][Image/][Container][Container][Image/][/Container][/Container][Container][Container][Container][Container][Title/][/Container][/Container][/Container][/Container]
Но это то, что мне нужно, когда я его запускаю. Как вы можете видеть, в нем отсутствует контейнер с заголовком (идентификатор sha
для контейнера и koo
для заголовка) и отсутствует заголовок (идентификатор rab
)
[Title/][Image/][Container][Container][Image/][Video/][/Container][Container][Title/][/Container][/Container][Container][Container][Container][Container][Title/][Image/][/Container][/Container][/Container][/Container]
Я чувствую, что, возможно, я близок, но я не могу понять, что я делаю не так. Как я могу получить недостающие данные?
Вот jsfiddle этого https://jsfiddle.net/gwxhymq4/5 /
Комментарии:
1. прежде всего, если
output
это массив, вы не можете добавлять к нему элементы с помощью. Вам нужно будет использовать
output.push(/*...*/)
2. @DanielCheung Технически вы можете — пустой массив будет преобразован в строку, в результате чего пустая строка будет объединена с выражением справа — но наличие массива в первую очередь не имеет никакого смысла, да.
3. @CertainPerformance да, я понимаю. Вот почему я называю это «добавлением элементов». Но та же мысль, это не имеет смысла.
Ответ №1:
Вместо findChildren(el.children[0])
этого вы должны использовать .map
для перебора всех дочерних элементов и получения результирующей строки (а не только первого дочернего элемента):
el.children.map(findChildren).join('')
или вызовите genStructure
снова, который использует ту же логику.
Кроме того, было бы более уместно либо инициализировать x
пустую строку, либо оставить ее полностью и только return
выражения внутри if
/ else
:
const arrayOfObjects = [
{"type": "Root", "id":0, "children" : [
{"type" : "Title", "id": "foo"},
{"type" : "Image", "id": "bar"},
{"type" : "Container", "id": "blo", "children":[
{"type" : "Container", "id": "goo", "children":[
{"type" : "Image", "id": "tar"},
{"type" : "Video", "id": "yar"}
]},
{"type" : "Container", "id": "sha", "children":[
{"type" : "Title", "id": "koo"},
]},
]},
{"type" : "Container", "id": "boo", "children":[
{"type" : "Container", "id": "bos", "children":[
{"type" : "Container", "id": "ooo", "children":[
{"type" : "Container", "id": "loo", "children":[
{"type" : "Title", "id": "bar"},
{"type" : "Image", "id": "rab"}
]}
]}
]}
]}
]}
]
const findChildren = (el) => {
if(el.type === "Container"){
return (
'[Container]'
mapChildren(el)
'[/Container]'
);
} else{
return '[' el.type '/]'
}
};
const mapChildren = (element) => {
return element.children.map(findChildren).join('');
}
console.log(mapChildren(arrayOfObjects[0]));
Комментарии:
1. Вместо
el.children.map(findChildren).join('')
этого я бы рекомендовал вызватьgenStructure(el.children)
, который OP подготовил именно для этой цели. (Конечно, его реализация должна быть исправлена или упрощена до того, что у вас есть)
Ответ №2:
const findChildren = (el) => {
let x = '';
if(el.type === "Container"){
el.children.forEach(function(child) {
x = findChildren(child)
});
return '[' el.type ']' x '[/' el.type ']';
}
else{
return '[' el.type '/]'
}
}
Ответ №3:
Это HTML-код.
<div id='meh'>
</div>
И это код JavaScript.
const arrayOfObjects = [
{"type": "Root", "id":0, "children" : [
{"type" : "Title", "id": "foo"},
{"type" : "Image", "id": "bar"},
{"type" : "Container", "id": "blo", "children":[
{"type" : "Container", "id": "goo", "children":[
{"type" : "Image", "id": "tar"},
{"type" : "Video", "id": "yar"}
]},
{"type" : "Container", "id": "sha", "children":[
{"type" : "Title", "id": "koo"},
]},
]},
{"type" : "Container", "id": "boo", "children":[
{"type" : "Container", "id": "bos", "children":[
{"type" : "Container", "id": "ooo", "children":[
{"type" : "Container", "id": "loo", "children":[
{"type" : "Title", "id": "bar"},
{"type" : "Image", "id": "rab"}
]}
]}
]}
] }
]}
]
const findChildren = (el) => {
let x = []
if(el.type === "Container"){
x = '[' el.type ']';
el.children.forEach(e => {
x = findChildren(e)
});
x = '[/' el.type ']';
return x
}
else{
return x = '[' el.type '/]'
}
}
genStructure = (data) => {
let output = []
data.forEach(function(el) {
output = findChildren(el)
});
return output
}
const el = document.getElementById("meh")
el.innerHTML = genStructure(arrayOfObjects[0].children)
И это результат.
[Title/][Image/][Container][Container][Image/][Video/][/Container][Container][Title/][/Container][/Container][Container][Container][Container][Container][Title/][Image/][/Container][/Container][/Container][/Container]