Если такие операции требуются часто, я бы сделал класс, хотя бы с минимально необходимыми функциями работы с деревом.
Ну как то так
class Node {
// Создает узел дерева.
// fields - объект с полями определяемыми пользователем
// childs - массив дочерних узлов (необязат)
constructor (fields, childs) {
this.parent = null;
this.childs = [];
for (const f in fields) {
this[f] = fields[f];
}
if (childs) {
for (const ch of childs) {
this.append(ch);
}
}
}
// Добавить узел nd, как последний дочерний к текущему
append (nd) {
nd.remove();
nd.parent = this;
this.childs.push(nd)
return this
}
// Найти в текущем и среди всех его потомков узел, удовлетворяющий условию,
// задаваемому функцией fcmp
find (fcmp) {
if (fcmp(this)) return this;
for (const ch of this.childs) {
const rf = ch.find (fcmp)
if (rf) return rf;
}
return null;
}
// Удалить узел
// nd.remove () удаляет узел nd из его родителя.
// par.remove (nd) удаляет из дочерних par узел nd
remove (nd) {
let par = this;
if (nd === undefined) {
par = this.parent;
nd = this;
}
if (!par || !nd) return
const ind = par.childs.indexOf(nd);
if (ind < 0) return;
par.childs.splice(ind, 1);
nd.parent = null;
return nd;
}
// Вставляет узел nd перед текущим, в его родительский узел, если он есть
before (nd) {
const par = this.parent;
if (!par) return;
nd.remove();
const ind = par.childs.indexOf(nd);
par.childs.splice(ind, 0, nd)
nd.parent = this;
return this;
}
toString () {
let s = '{'
for (const f in this) {
if (f == 'childs') continue;
if (f == 'parent') continue;
s += `${f}: ${this[f].toString()}, `
}
s+='childs: ['
for (const ch of this.childs) {
s+=ch.toString() + ','
}
s+=']}'
return s
}
}
const tree1 = new Node ({},
[
new Node ({id: 1, title: 'node1'},
[
new Node ({id: 3, title: 'sub node1'}),
new Node ({id: 4, title: 'sub node1'}, [new Node ({ id: 5, title: 'sub sub node1'})]),
]),
new Node ({id: 2, title: 'node2'},
[
new Node ({id: 6, title: 'sub node2'}),
new Node ({id: 7, title: 'sub node2'}, [new Node ({ id: 8, title: 'sub sub node2'})]),
])
]);
const tree2 = new Node ({},
[
new Node ({id: 9, title: 'node1'},
[
new Node ({id: 10, title: 'sub node1'}),
new Node ({id: 11, title: 'sub node1'}),
]),
new Node ({id: 12, title: 'node2'},
[
new Node ({id: 13, title: 'sub node2'}),
new Node ({id: 14, title: 'sub node2'}, [new Node ({ id: 15, title: 'sub sub node2'})]),
])
]);
console.log(tree1.toString());
console.log(tree2.toString());
// Допустим я беру и удаляю ноду из tree2:
// и ее вставляю в tree1 между:
const nd12 = tree2.find (nd => nd.id == 12)
const nd7 = tree1.find (nd => nd.id == 7)
nd7.before(nd12)
console.log(tree1.toString());
console.log(tree2.toString());