Answer the question
In order to leave comments, you need to log in
How to properly traverse an array to build a tree?
It is necessary to form a nested structure (tree) from an array. The traversal path can be taken from the "name" field of each nodes element.
How nesting is defined: Each element has a name field. The last substring from the right after the slash in this field is the title of the current element. Further, in order to get the parent or children of a given element, it is necessary to take the substring to the left or the substring to the right of it, respectively, and thus accumulate the accumulator, going through each element.
A single element in the original nodes collection can have multiple children. If the element has no children, then its field isDirectory === false, otherwise isDirectory === true.
Initial data:
const nodes = [
{
"id": 0,
"name": "\"Корень\"",
"createDate": "2018-12-11T14:40:26.95",
"updateDate": "2018-12-11T14:40:26.95",
"folderId": -1,
"ctnsCount": 0,
"ctnsCountDate": "2018-12-11T14:40:26.95",
"audiences": [0, 0, 0, 0]
},
{
"id": 1000831,
"name": "\"Store/Сегменты для OPS/Сегменты для внешней рекламы/Автодилеры\"",
"createDate": "2018-12-29T03:04:28.26",
"updateDate": "2018-12-29T03:04:28.26",
"folderId": -1,
"ctnsCount": 23511,
"ctnsCountDate": "2019-01-09T05:48:23.487",
"audiences": []
},
{
"id": 1000249,
"name": "\"Store/Сегменты для OPS/Сегменты для внешней рекламы\"",
"createDate": "2018-12-11T14:40:42.313",
"updateDate": "2018-12-11T14:40:42.313",
"folderId": -1,
"ctnsCount": 1490426,
"ctnsCountDate": "2019-01-09T05:48:04.827",
"audiences": []
},
{
"id": 1000032,
"name": "\"Store/Сегменты для OPS\"",
"createDate": "2018-12-11T14:40:19.48",
"updateDate": "2018-12-11T14:40:19.48",
"folderId": -1,
"ctnsCount": 0,
"ctnsCountDate": "2018-12-11T14:40:19.48",
"audiences": []
},
{
"id": 28473,
"name": "\"Store\"",
"createDate": "2018-12-11T14:40:32.733",
"updateDate": "2018-12-11T14:40:32.733",
"folderId": -1,
"ctnsCount": 0,
"ctnsCountDate": "2018-12-11T14:40:32.733",
"audiences": []
},
{
"id": 1000772,
"name": "\"Store/Сегменты для OPS/Сегменты для внешней рекламы/Cian\"",
"createDate": "2018-12-11T14:40:05.02",
"updateDate": "2018-12-11T14:40:05.02",
"folderId": -1,
"ctnsCount": 30409,
"ctnsCountDate": "2019-01-09T05:48:20.673",
"audiences": []
},
{
"id": 2681,
"name": "\"Сегменты Facetz/Образ жизни/Обзоры",
"createDate": "2018-12-11T14:40:30.623",
"updateDate": "2018-12-11T14:40:30.623",
"folderId": -1,
"ctnsCount": 115379,
"ctnsCountDate": "2019-01-09T05:48:23.847",
"audiences": []
},
{
"id": 3840,
"name": "\"Сегменты Facetz/Образ жизни\"",
"createDate": "2018-12-11T14:39:46.45",
"updateDate": "2018-12-11T14:39:46.45",
"folderId": -1,
"ctnsCount": 0,
"ctnsCountDate": "2018-12-11T14:39:46.45",
"audiences": []
},
{
"id": 3811,
"name": "\"Сегменты Facetz\"",
"createDate": "2018-12-11T14:39:46.373",
"updateDate": "2018-12-11T14:39:46.373",
"folderId": -1,
"ctnsCount": 0,
"ctnsCountDate": "2018-12-11T14:39:46.373",
"audiences": []
}
];
const result = [
{
id: 0,
title: 'Корень',
isDirectory: true,
children: [
{
id: 28473,
title: 'Store',
isDirectory: true,
children: [
{
id: 1000032,
title: 'Сегменты для OPS',
isDirectory: true,
children: [
{
id: 1000249,
title: 'Сегменты для внешней рекламы',
isDirectory: true,
children: [
{
id: 1000831,
title: 'Автодилеры',
isDirectory: false,
},
{
id: 1000772,
title: 'Cian',
isDirectory: false,
}
]
}
]
}
]
},
{
id: 3811,
title: 'Сегменты Facetz',
isDirectory: true,
children: [
{
id: 3840,
title: 'Образ жизни',
isDirectory: true,
children: [
{
id: 2681,
title: 'Обзоры',
isDirectory: false
}
]
}
]
}
]
}
]
const traverseItems = (acc, currentNode, index, allNodes) => {
const path = currentNode.name.split('/');
const title = path[path.length - 1].replace(/("|')/g, '');
const id = currentNode.id;
const currentChildren = allNodes
.filter(n => n.id !== id)
.filter(n => n.name.includes(title));
const isDirectory = currentChildren.length > 0 || id === 0;
if (isDirectory) {
return acc.concat([{
id,
title,
isDirectory,
children: currentChildren.reduce(traverseItems, acc)
}]);
} else {
return acc.concat([{ id, title, isDirectory }]);
}
};
const result = nodes.reduce(traverseItems, []);
Answer the question
In order to leave comments, you need to log in
function getTree(data) {
let root = data.find(n => n.id === 0);
root = { title: root.name.slice(1,-1), id: root.id };
data.filter(n => n.id !== 0).forEach(item => {
const node = item.name.slice(1, -1).split('/').reduce((parent, title) => {
if (!parent.children) {
Object.assign(parent, { children: [], isDirectory: true });
}
let child = parent.children.find(m => m.title === title);
if (!child) {
child = { title };
parent.children.push(child);
}
return child;
}, root);
Object.assign(node, { id: item.id, isDirectory: !!node.isDirectory });
});
return root;
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question