Skip to content

Instantly share code, notes, and snippets.

@tsabirgaliev
Last active January 19, 2017 17:52
Show Gist options
  • Save tsabirgaliev/2e501fc08b2ed2e8b0bf00d19d6cf9e8 to your computer and use it in GitHub Desktop.
Save tsabirgaliev/2e501fc08b2ed2e8b0bf00d19d6cf9e8 to your computer and use it in GitHub Desktop.
Persistent immutable tree update function
interface TreeNode {
id: number;
children: TreeNode[];
}
/* основная идея в том, чтобы не менять узел, если не менялись дочерние */
function updateTree(tree: TreeNode, id: number, node: TreeNode) {
if (tree.id === id) { // мы нашли нужную ноду
return {
...tree,
children: [...tree.children, node]
};
} else { // ищем в дочерних, и вероятно обновляем
let childrenChanged: boolean = false; // надеемся, что не будет обновления
let newChildren = tree.children.map(subtree => {
let newSubtree = updateTree(subtree, id, node);
if (subtree !== newSubtree) { // отмечаем, что обновление все таки было
childrenChanged = true;
}
return newSubtree;
});
if (childrenChanged) { // обновилось? -> строим новый узел
return {
...tree,
children: newChildren
};
} else { // иначе, возвращаем старый
return tree;
}
}
}
let tree: TreeNode = {
id: 1,
children: []
};
let newTree = updateTree(tree, 1, {id: 2, children: []});
console.log(newTree);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment