Сначала вы можете создать Map
, который имеет в качестве ключей значения свойств name
, а в качестве соответствующих значений - (незаконченные) объекты результатов. Они начинаются только со свойства name
.
Затем вы можете перебирать информацию children
во входных данных, чтобы связать children
с вышеупомянутыми объектами результатов, что может быть эффективно выполнено с помощью name
в качестве ключа в Map
.
Всякий раз, когда вы подключаете дочерний объект к родительскому объекту, вы знаете, что этот дочерний объект не является объектом верхнего уровня в конечном результате. Итак, начиная с всех узлов, вы должны обрезать этот список (a Set
) всех тех узлов, которые встречаются в массиве children
. Это оставит вас только с узлами верхнего уровня, которые в форме массива представляют желаемый результат.
Реализация:
let data = [{"name": "7654321","children": [{"_id": "LjYgocn9PsHhEFbM7","accountId": "4343213"},{"_id": "sB2ipCstYnLnHrAuu","accountId": "4343271"},{"_id": "JhugmhxS7A57Y34wM","accountId": "4343276"}]},{"name": "4343213","children": []},{"name": "4343271","children": [{"_id": "sie9mtttgdRw7Ktma","accountId": "4343279"}]},{"name": "4343279","children": [{"_id": "sie23mtttgdRw7Ktma","accountId": "8765345"}]},{"name": "4343276","children": []}];
let map = new Map(data.map(({name, children}) => [name, { name }]));
let roots = new Set(map.values());
for (let {name, children} of data) {
if (!children?.length) continue;
map.get(name).children = children.map(({accountId}) => {
let child = map.get(accountId) || { name: accountId };
roots.delete(child);
return child;
});
}
let result = Array.from(roots);
console.log(result);