Я думаю, что итеративный подход более читабелен, поэтому, возможно, предоставленное решение поможет вам понять, как это делается (хотя оно слегка вдохновлено ответом Нины)
Итак, мы делаем итерацию по всем объектам всписок.Первоначально для каждого объекта мы устанавливаем текущий список узлов в качестве конечного дерева.И мы повторяем по длине идентификаторов.
Сначала мы создаем идентификатор из списка идентификаторов, разделяя массив ids
на постепенно увеличивающиеся фрагменты с помощью slice
(['1'], ['1', '2'], ['1', '2', '6') и объединить в строку с :
.Таким образом, мы получаем идентификаторы 1, 1: 2, 1: 2: 6 для первого элемента.
Далее мы находим узел в currentNodelist
по ранее созданному идентификатору.Если мы не можем найти узел, это означает, что мы еще не добавили его, поэтому нам нужно создать и добавить его (если мы его найдем, нам не нужно добавлять его).
На следующем шагенам нужно углубиться в дерево, поэтому мы назначаем дочерние узлы созданного в данный момент (или того, которого мы нашли) как currentNodelist
.С этим мы пройдем дерево глубже, предоставив идентификаторы.
let objs = [
{ id: '1:2:6', ids: ['1', '2', '6'] },
{ id: '1:4', ids: ['1', '4'] },
{ id: '1', ids: ['1'] },
{ id: '1:2', ids: ['1', '2'] },
];
let tree = [];
for (let i = 0; i < objs.length; i++) {
let obj = objs[i];
let currentNodeList = tree;
for (let j = 0; j < obj.ids.length; j++) {
let id = obj.ids.slice(0, j + 1).join(':');
let currentNode = currentNodeList.find((node) => node.id === id);
if (!currentNode) {
currentNode = {id, children: []};
currentNodeList.push(currentNode);
}
currentNodeList = currentNode.children;
}
}
console.log(tree);
Я создал простой gif, который показывает, что происходит в первых двух итерациях.Стрелка указывает на currentListNode
.
![enter image description here](https://i.stack.imgur.com/uEKxv.gif)