попытался решить все через рекурсию
Рекурсией конечно можно:
const createTree = (data, idKey, parentKey, parentId) =>
data.reduce((acc, n) => (parentId === n[parentKey] && acc.push({
...n,
children: createTree(data, idKey, parentKey, n[idKey]),
}), acc), []);
const tree = createTree(data, 'id', 'parentId', null);
Но вовсе не обязательно:
function createTree(data, idKey, parentKey) {
const tree = Object.fromEntries(data.map(n => [ n[idKey], { ...n, children: [] } ]));
return Object
.values(tree)
.filter(n => !(tree[n[parentKey]] && tree[n[parentKey]].children.push(n)));
}
const tree = createTree(data, 'id', 'parentId');