Дан массив объектов:
let arr = [
{
id: 1000,
name: "Like",
parent_id: 1003,
parent_name: "Root"
},
{
id: 1001,
name: "Count",
parent_id: 1000,
parent_name: "Like"
},
{
id: 1002,
name: "Subscribe",
parent_id: "",
parent_name: ""
},
{
id: 1003,
name: "Root",
parent_id: "",
parent_name: ""
}
];
Задача - преобразовать его в следующий вид:
track = {
1000: '/ > Root>Like',
1001: '/ > Root>Like > Count',
1002: '/ > Subscribe',
1003: '/ > Root'
}
Суть функции - преобразовать массив в объект, в котором ключами будут значения id из объектов массива, а значениями этих ключей будут пути, формирующиеся по принципу: если в ключе parent_id пустая строка - возвращается имя данного объекта, это, стало быть базовый случай в рекурсивной функции, но если в parent_id есть значение, то возвращается значение name и происходит поиск объекта у которого значение id равно значению parent_id данного объекта и возвращается его name тоже и т.д.
Базовый случай понятно как прописать:
for(let i in arr) {
if(arr[i].parent_id == "") {
ans[arr[i].id] = '/ ' + arr[i].name
}
}
Но вот рекурсивно "пробегать" все объекты не получается реализовать.
let arr = [
{
id: 1000,
name: "Like",
parent_id: 1003,
parent_name: "Root"
},
{
id: 1001,
name: "Count",
parent_id: 1000,
parent_name: "Like"
},
{
id: 1002,
name: "Subscribe",
parent_id: "",
parent_name: ""
},
{
id: 1003,
name: "Root",
parent_id: "",
parent_name: ""
}
];
//метод для рекурсивного обхода массива
function recursion(parent_id, arResult = []) {
for (let item of arr) {
//если переданный parent_id равен id в массиве
if (item.id === parent_id) {
//добавляем имя родителя в начало массива
arResult.unshift(item.name);
//если в этой итерации есть parent, то идём получаеть его имя
if (!!item.parent_id) {
recursion(item.parent_id, arResult);
}
continue;
}
}
//массив превращаем в строку с делителем '>'
return `${arResult.join(">")} > `;
}
let objResult = {}, parentName = "";
for (let item of arr) {
//parentName всегда пустой на новой итерации
parentName = '';
//если parent_id заполнен
if (!!item.parent_id) {
//если у элемента в итерации есть parent, то идём получаеть его имя
parentName = recursion(item.parent_id, []);
}
//собираем результат
objResult[item.id] = `/ > ${parentName}${item.name}`;
}
console.log(objResult);
получилось так
const abra = (arr) => {
let ans = {}
const way = '>'
let el
const catabra = (inner) => {
if(typeof inner === 'object'){
el = arr.find(el => inner.parent_id === el.id)
return el?.parent_name ?
'/' + catabra(el.parent_name) + catabra(inner.parent_name) + catabra(inner.name) :
inner.parent_name ?
'/' + catabra(inner.parent_name) + catabra(inner.name) :
'/' + catabra(inner.name)
}
return way + inner
}
arr.forEach((elem) => {
ans[elem.id] = catabra(elem)
})
return ans
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
У меня есть координаты первой точки на карте, есть расстояние между точками и есть градусы поворота относительно сторон света (с компаса)Подскажите...