// Рекурсия: HTML tree
// Используя решение этого задания сделайте функцию, которая рекурсивно создает HTML-строку из древовидной
// структуры данных Javascript любой вложенности. Проверьте результат работы функции выводя HTML-строку
// используя document.write или же какой-то_элемент.innerHTML
html_tree: {
function htmlTree(element) {
let str = '';
let attrStr = '';
if (element.attrs) {
Object.keys(element.attrs).forEach(key => {
attrStr += `${key}=${element.attrs[key]} `
});
}
str += `<${element.tagName} ${attrStr}>`
if (element.children) {
for (let childIndex in Object.keys(element.children)) {
if (element.children[childIndex].tagName) {
str += htmlTree(element.children[childIndex]);
} else {
str += `${element.children}`;
}
}
}
str += `${element.tagName}>`;
return str;
}
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"],
},
]
}
]
}
document.write(htmlTree(table));
}
// Рекурсия: DOM tree
// Используя решение этого задания сделайте функцию, которая рекурсивно создает DOM из древовидной структуры
// данных Javascript. Задание в целом аналогично предыдущему, однако вместо накопления результата в HTML-строке
// функция должна добавлять элементы созданные через document.createElement в переданного в функцию родителя.
dom_tree: {
function domTree(parent, element) {
let el = document.createElement(element.tagName);
if (element.attrs) {
Object.keys(element.attrs).forEach(key => {
el[key] = element.attrs[key];
});
}
parent.append(el);
if (element.children) {
for (let childIndex in Object.keys(element.children)) {
if (element.children[childIndex].tagName) {
domTree(el, element.children[childIndex]);
} else {
el.innerText = element.children;
}
}
}
}
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, в которых
// нет циклических связей.
deep_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"],
},
]
}
]
}
const arr = [1, "string", null, undefined, { a: 15, b: 10, c: [1, 2, 3, 4], d: undefined, e: true }, true, false]
function deepCopy(obj) {
let copy;
if (Array.isArray(obj)) {
copy = [];
} else {
copy = {};
}
if (obj) {
Object.keys(obj).forEach(key => {
if (typeof obj[key] == 'object') {
copy[key] = deepCopy(obj[key]);
} else {
copy[key] = obj[key];
}
});
}
return copy;
}
const arr2 = deepCopy(arr); //arr2 и все его вложенные массивы и объекты - другие объекты, которые можно менять без риска поменять что-то в arr
console.log(arr2);
const table2 = deepCopy(table); //аналогично
console.log(table2);
}
// Рекурсия: My Stringify
// Напишите аналог JSON.stringify
my_stringify: {
function stringify(obj) {
let str = '';
let length = Array.isArray(obj) ? obj.length : Object.keys(obj).length;
if (typeof obj == 'object') {
str += Array.isArray(obj) ? '[' : '{';
}
Object.keys(obj).forEach((key, i) => {
if (!Array.isArray(obj)) {
str += `"${key}":`;
}
if (typeof obj[key] == 'object' && obj[key] != null) {
str += stringify(obj[key]);
} else if (typeof obj[key] == 'string') {
str += `"${obj[key]}"`;
} else if (obj[key] == undefined) {
str += `null`;
} else {
str += `${obj[key]}`;
}
if (i != length - 1) {
str += ',';
}
});
if (typeof obj == 'object') {
str += Array.isArray(obj) ? ']' : '}';
}
return str;
}
const arr = [1, "string", null, undefined, { a: 15, b: 10, c: [1, 2, 3, 4], d: undefined, e: true }, true, false];
const jsonString = stringify(arr); //напишите функцию stringify без использования JSON.stringify
console.log(jsonString);
console.log(JSON.parse(jsonString));//не должно поломаться и должно вернуть структуру, во всем схожую с оригинальным arr или table
}
// Рекурсия: getElementById throw
// Напишите функцию getElementById, которая будет аналогична document.getElementById. В качестве основы можете
// взять материал лекции (walker), однако в цикл перебора children вставьте проверку на нахождение
// переданного id. При нахождении элемента по id в рекурсивной функции выбрасывайте исключение со значением
// найденного DOM-элемента, которое будет поймано на уровне вашей функции getElementById, после чего она
// вернет выброшенный DOM-элемент.
get_element_by_id: {
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 e;
}
}
console.log(getElementById('wantedParagraph'));
}