Задача: Реализуйте функцию buildHtml, которая возвращает строковое представление html.
Входные данные:
const data = ['html', [
['head', [
['title', 'hello, hexlet!'],
]],
['body', { class: 'container' }, [
['h1', { class: 'header' }, 'html builder example'],
['div', [
['span'],
['span', { class: 'text', id: 'uniq-key' }],
]],
]],
]];
]];
Строка на выходе:
<html><head><title>hello, world!</title></head><body class="container"><h1 class="header">html builder example</h1><div><span></span><span class="text" id="uniq-key"></span></div></body></html>
Решение не мое, я лишь пытаюсь разобрать его, хочу для начала разобрать каждый шаг, а потом попробовать решить задачу самостоятельно уже с пониманием. Не понимаю эту строку return { ...acc, [name]: arg }, объясните пожалуйста, если возможно с приведением примеров, что же тут происходит. С оператором ... я знаком, но в таком варианте встречаю впервые.
Решение:
const propertyActions = [
{
name: 'body',
check: arg => typeof arg === 'string',
},
{
name: 'children',
check: arg => arg instanceof Array,
},
{
name: 'attributes',
check: arg => arg instanceof Object,
},
];
const getPropertyAction = arg => propertyActions.find(({ check }) => check(arg));
const buildAttrString = attrs =>
Object.keys(attrs).map(key => ` ${key}="${attrs[key]}"`).join('');
const buildHtml = (data) => {
const tag = data.slice(1)
.reduce((acc, arg) => {
const { name } = getPropertyAction(arg);
return { ...acc, [name]: arg };
}, { name: data[0], attributes: {}, body: '', children: [] });
return [`<${tag.name}${buildAttrString(tag.attributes)}>`,
`${tag.body}${tag.children.map(buildHtml).join('')}`,
`</${tag.name}>`,
].join('');
};