// Рекурсия: HTML tree
// Используя решение этого задания сделайте функцию, которая рекурсивно создает HTML - строку из древовидной структуры данных Javascript любой вложенности.Проверьте результат работы функции выводя HTML - строку используя document.write или же какой - то_элемент.innerHTML
{
function htmlTree(data) {
let copy
copy = `<${data.tagName}`
if (data.attrs) {
for (const [attrName, attrParam] of Object.entries(data.attrs)) {
copy += ` ${attrName}='${attrParam}'`
}
}
copy += `>`
if (data.children) {
for (const child of data.children) {
typeof child === 'object' ? copy += htmlTree(child) : copy += `${child}`
}
}
copy += `${data.tagName}>`
return copy
}
// Проверка
const table = {
tagName: 'table',
attrs: {
border: "1",
},
children: [
{
tagName: 'tr',
children: [
{
tagName: "td",
children: ["1x1"],
},
{
tagName: "td",
children: ["1x2"],
},
]
},
{
tagName: 'tr',
children: [
{
tagName: "td",
children: ["2x1"],
},
{
tagName: "td",
children: ["2x2"],
},
]
}
]
}
htmlTree(table)
document.write(htmlTree(table))
}
// Рекурсия: DOM tree
// Используя решение этого задания сделайте функцию, которая рекурсивно создает DOM из древовидной структуры данных Javascript.Задание в целом аналогично предыдущему, однако вместо накопления результата в HTML - строке функция должна добавлять элементы созданные через document.createElement в переданного в функцию родителя.
{
function domTree(parent, data) {
const tag = document.createElement(data.tagName)
if (data.attrs) {
for (const [attrName, attrParam] of Object.entries(data.attrs)) {
tag[attrName] = attrParam
}
}
parent.append(tag)
if (data.children) {
for (const child of data.children) {
typeof child === 'object' ? domTree(tag, child) : tag.innerHTML = child
}
}
}
// Проверка
const table = {
tagName: 'table',
attrs: {
border: "1",
},
children: [
{
tagName: 'tr',
children: [
{
tagName: "td",
children: ["1x1"],
},
{
tagName: "td",
children: ["1x2"],
},
]
},
{
tagName: 'tr',
children: [
{
tagName: "td",
children: ["2x1"],
},
{
tagName: "td",
children: ["2x2"],
},
]
}
]
}
domTree(document.body, table)
}
// Рекурсия: Deep Copy
// Напишите функцию, которая рекурсивно осуществляет глубокое копирование структур Javascript, в которых нет циклических связей.
{
function deepCopy(data) {
let copy
if (Array.isArray(data)) {
copy = []
} else if (typeof data === 'object' && data !== null) {
copy = {}
} else return data
for (const item in data) {
copy[item] = deepCopy(data[item])
}
return copy
}
// Проверка
const arr = [1, "string", null, undefined, { a: 15, b: 10, c: [1, 2, 3, 4], d: undefined, e: true }, true, false]
const arr2 = deepCopy(arr) //arr2 и все его вложенные массивы и объекты - другие объекты, которые можно менять без риска поменять что-то в arr
const table = {
tagName: 'table',
attrs: {
border: "1",
},
children: [
{
tagName: 'tr',
children: [
{
tagName: "td",
children: ["1x1"],
},
{
tagName: "td",
children: ["1x2"],
},
]
},
{
tagName: 'tr',
children: [
{
tagName: "td",
children: ["2x1"],
},
{
tagName: "td",
children: ["2x2"],
},
]
}
]
}
const table2 = deepCopy(table) //аналогично
}
// Рекурсия: My Stringify
// Напишите аналог JSON.stringify
{
function stringify(data) {
let copy = ''
if (Array.isArray(data)) {
copy += `[`
} else if (typeof data === 'object' && data !== null) {
copy += `{`
} else return data
for (const item in data) {
if (data[item] == undefined) {
copy += `${null}`
} else if (typeof data[item] === 'number' || typeof data[item] === 'boolean') {
copy += `${data[item]}`
} else if (typeof data[item] === 'string') {
copy += `"${data[item]}"`
} else if (typeof data[item] === 'object' && data[item] !== null) {
if (typeof data === 'object' && data !== null) {
copy += `{`
let i = 1
for (const [key, value] of Object.entries(data[item])) {
if (value == undefined) {
data[item][key] = null
} else if (typeof value !== 'object') {
copy += `"${key}":` + (typeof value === 'string' ? `"${value}"` : value)
if (i < Object.keys(data[item]).length) copy += ','
} else {
copy += `"${key}":${stringify(value)}`
copy += ','
}
i++
}
}
copy += `}`
} else {
copy += `${stringify(data[item])}`
}
if (item < (data.length - 1)) copy += ','
}
copy += `${Array.isArray(data) ? ']' : '}'} `
return copy
}
const number = [1, 2, 3, false, "string", { a: 10, b: 'stepan' }]
let test = stringify(number)
console.log('sourse: ', JSON.stringify(number))
console.log('sourse reverse: ', JSON.parse(JSON.stringify(number)))
console.log('===============================================================================================')
console.log('result: ', test)
console.log('result reverse: ', JSON.parse(test))
const arr = [1, "string", null, undefined, { a: 15, b: 10, c: [1, 2, 3, 4], d: undefined, e: true }, true, false]
let jsonString = stringify(arr)
console.log('sourse: ', JSON.stringify(arr))
console.log('sourse reverse: ', JSON.parse(JSON.stringify(arr)))
console.log('===============================================================================================')
console.log('result: ', jsonString)
console.log('result reverse: ', JSON.parse(jsonString))
// пока не работает
let tableParse = stringify(table)
console.log('sourse: ', JSON.stringify(table))
console.log('sourse reverse: ', JSON.parse(JSON.stringify(table)))
console.log('===============================================================================================')
console.log('result: ', tableParse)
console.log('result reverse: ', JSON.parse(tableParse))
}
// Рекурсия: getElementById throw
// Напишите функцию getElementById, которая будет аналогична document.getElementById.В качестве основы можете взять материал лекции(walker), однако в цикл перебора children вставьте проверку на нахождение переданного id.При нахождении элемента по id в рекурсивной функции выбрасывайте исключение со значением найденного DOM - элемента, которое будет поймано на уровне вашей функции getElementById, после чего она вернет выброшенный DOM - элемент.
{
function getElementById(idToFind) {
function walker(parent = document.body) {
for (const child of parent.children) {
if (child.id == idToFind) {
throw child
}
walker(child)
}
}
try {
walker()
}
catch (e) {
return console.log(e)
}
}
// http://doc.a-level.com.ua/five-recursion-try-catch-finally-homework
getElementById('h1-1_0')
}