отсортировать масиив по глубине ветвей (все дочерние элементы следуют за родителем)
Есть массив данных, который необходимо отсортировать:
const array = [{
_id: 5,
title: 'vueJS',
parent: {_id: 3}
}, {
_id: 6,
title: 'reactJS',
parent: {_id: 3}
}, {
_id: 3,
title: 'js',
parent: {_id: 1}
}, {
_id: 1,
title: 'dev',
parent: null
}, {
_id: 4,
title: 'photoshop',
parent: {_id: 2}
}, {
_id: 2,
title: 'UX',
parent: null
}];
```
Вернуть так же плоский массив но уже с другим порядком (дочерние элементы после родительских):
```
array = [{
_id: 1,
title: 'dev',
parent: null
}, {
_id: 3,
title: 'js',
parent: {_id: 1}
}, {
_id: 5,
title: 'vueJS',
parent: {_id: 3}
}, {
_id: 6,
title: 'reactJS',
parent: {_id: 3}
}, {
_id: 2,
title: 'UX',
parent: null
}, {
_id: 4,
title: 'photoshop',
parent: {_id: 2}
}];
```
Дополнительно.
Глубину можно показать добавив символ в начало title:
```
array = [{
_id: 1,
title: 'dev',
parent: null
}, {
_id: 3,
title: '-js',
parent: {_id: 1}
}, {
_id: 5,
title: '--vueJS',
parent: {_id: 3}
}, {
_id: 6,
title: '--reactJS',
parent: {_id: 3}
}, {
_id: 2,
title: 'UX',
parent: null
}, {
_id: 4,
title: '-photoshop',
parent: {_id: 2}
}];
```
Ответы (3 шт):
Автор решения: rureeru
→ Ссылка
const array = [{
_id: 5,
title: 'vueJS',
parent: {_id: 3}
}, {
_id: 6,
title: 'reactJS',
parent: {_id: 3}
}, {
_id: 3,
title: 'js',
parent: {_id: 1}
}, {
_id: 1,
title: 'dev',
parent: null
}, {
_id: 4,
title: 'photoshop',
parent: {_id: 2}
}, {
_id: 2,
title: 'UX',
parent: null
}];
const convert = (data) => {
// создаем ассоциативный массив с ключами айдишниками и добавляем к элементу поле children
let mapList = {}
data.forEach(item => mapList[item._id] = { ...item, children: [] })
// console.log(mapList)
// собираем дерево
let tree = []
Object.values(mapList).forEach(item => {
if (!item.parent) {
tree.push(item)
} else {
console.log(mapList[item.parent._id])
mapList[item.parent._id].children.push(item)
}
})
// console.log(tree)
// обходим дерево рекурсивно и отбираем данные с форматированным title
const treeToFlatList = (tree, level = 0) => {
let result = []
tree.forEach(treeItem => {
let { children, ...item } = treeItem
item.title = '-'.repeat(level) + item.title
result.push(item)
result = result.concat(treeToFlatList(children, level + 1))
})
return result
}
return treeToFlatList(tree)
}
console.log(convert(array))
Автор решения: rureeru
→ Ссылка
const array = [{
_id: 5,
title: 'vueJS',
parent: {_id: 3}
}, {
_id: 6,
title: 'reactJS',
parent: {_id: 3}
}, {
_id: 3,
title: 'js',
parent: {_id: 1}
}, {
_id: 1,
title: 'dev',
parent: null
}, {
_id: 4,
title: 'photoshop',
parent: {_id: 2}
}, {
_id: 2,
title: 'UX',
parent: null
}
];
const getFullTree = (arr, parent = null, inner = 0) => {
return arr.reduce((arr, elem) => {
if (elem.parent && elem.parent._id !== parent) {
return arr;
}
const title = inner
? `${'-'.repeat(inner)}${elem.title}`
: elem.title;
arr.push({
...elem,
title,
});
const children = array.filter((item) => item.parent && item.parent._id === elem._id);
if(!children) {
return arr;
}
const childArr = getFullTree(children, elem._id, inner + 1);
return arr.concat(childArr);
}, []);
}
const result = getFullTree(array);
console.log('\n\nresult: ', result);
// result = [
// {_id: 1, title: 'dev',parent: null},
// { _id: 3, title: '-js', parent: {_id: 1}},
// {_id: 5, title: '--vueJS', parent: {_id: 3} },
// {_id: 6, title: '--reactJS', parent: {_id: 3} },
// { _id: 2, title: 'UX', parent: null },
// { _id: 4, title: '-photoshop', parent: {_id: 2} }
// ];
Автор решения: rureeru
→ Ссылка
const array = [{
_id: 5,
title: 'vueJS',
parent: {_id: 3}
}, {
_id: 6,
title: 'reactJS',
parent: {_id: 3}
}, {
_id: 3,
title: 'js',
parent: {_id: 1}
}, {
_id: 1,
title: 'dev',
parent: null
}, {
_id: 4,
title: 'photoshop',
parent: {_id: 2}
}, {
_id: 2,
title: 'UX',
parent: null
}
];
const getFullTree = (rootArray) => {
const getTree = (array, parent = null, inner = 0) => {
return array.reduce((arr, elem) => {
if (elem.parent && elem.parent._id !== parent) {
return arr;
}
arr.push({
...elem,
title: `${'-'.repeat(inner)}${elem.title}`,
});
const children = rootArray.filter((item) => item.parent && item.parent._id === elem._id);
if(!children) {
return arr;
}
const childArr = getTree(children, elem._id, inner + 1);
return arr.concat(childArr);
}, []);
}
return getTree(rootArray);
}
// const result = getFullTree(array);
console.log('result: ', getFullTree(array));
// array = [
// {_id: 1, title: 'dev',parent: null},
// { _id: 3, title: '-js', parent: {_id: 1}},
// {_id: 5, title: '--vueJS', parent: {_id: 3} },
// {_id: 6, title: '--reactJS', parent: {_id: 3} },
// { _id: 2, title: 'UX', parent: null },
// { _id: 4, title: '-photoshop', parent: {_id: 2} }
// ];