tree-fns
tree-fns provides simple utility functions for tree structure.
Each transformation function is non-destructive, making it suitable for working with immutable tree structures.
Development
Prerequisite
- deno >= 1.20
Model
const tree: TreeNode = {
id: "root",
children: [
{
id: "1",
children: [],
},
{
id: "2",
children: [],
},
],
};
const tree: TreeNode<{ data: string }> = {
id: "root",
data: "yay",
children: [],
};
Functions
walk(tree, visit)
Only pre-order traversing is supported.
walk(
{
id: "root",
children: [
{
id: "1",
children: [{ id: "1-1", children: [] }],
},
{
id: "2",
children: [{ id: "2-1", children: [] }],
},
],
},
(node, location) => {
console.log(node.id); // "root" -> "1" -> "1-1" -> "2" -> "2-1"
if (node.id === "1") {
console.log(location); // { parentPath: ["root"], index: 0 }
}
},
);
findNode(tree, test)
| findNodeById(tree, id)
const tree: TreeNode = {
id: "root",
children: [
{
id: "1",
children: [{ id: "1-1", children: [] }],
},
{
id: "2",
children: [{ id: "2-1", children: [] }],
},
],
};
const node = findNode(tree, (node) => node.id === "1");
// [
// {
// id: '1',
// children: [{ id: '1-1', children: [] }],
// },
// {
// parentPath: ['root'],
// index: 0,
// },
// ]
findNode(tree, (node) => node.id === "x"); // undefined
or
const node = findNodeById(tree, "1");
map(tree, mapNode)
const tree: TreeNode<{ data: string }> = {
id: "1",
data: "foo",
children: [
{
id: "2",
data: "bar",
children: [],
},
],
};
const mapped = map<{ data: string }>(tree, (node) => ({
...node,
data: `#${node.data}`,
}));
// {
// id: '1',
// data: '#foo',
// children: [
// {
// id: '2',
// data: '#bar',
// children: [],
// },
// ],
// }
copy(tree)
const tree = {
id: "1",
children: [{ id: "2", children: [] }],
};
const copied = copy(tree);
// {
// id: '1',
// children: [{ id: '2', children: [] }],
// }
console.log(tree === copied); // false
addNode(tree, nodeToBeAdded, dest)
const srcTree = {
id: "1",
children: [{ id: "2", children: [] }],
};
const nodeToBeAdded = { id: "3", children: [] };
const destTree = addNode(srcTree, nodeToBeAdded, { parentId: "1", index: 0 });
// {
// id: '1',
// children: [
// { id: '3', children: [] },
// { id: '2', children: [] },
// ],
// }
removeNode(tree, id)
const srcTree = {
id: "1",
children: [
{ id: "2", children: [] },
{ id: "3", children: [] },
],
};
const [destTree, removedNode] = removeNode(srcTree, "3");
console.log(removedNode); // { id: '3', children: [] }
console.log(destTree);
// {
// id: '1',
// children: [
// { id: '2', children: [] },
// ],
// }
removeNode(srcTree, "x"); // undefined
moveNode(tree, id, dest)
const srcTree = {
id: "1",
children: [
{ id: "2", children: [] },
{ id: "3", children: [] },
],
};
const destTree = moveNode(srcTree, "2", { parentId: "3", index: 0 });
// {
// id: '1',
// children: [
// { id: '3', children: [
// { id: '2', children: [] }
// ] }
// ],
// }
flatten(tree)
const tree = {
id: "1",
children: [
{ id: "2", children: [] },
{ id: "3", children: [] },
],
};
const flattened = flatten(tree);
// [
// [
// {
// id: '1',
// children: [
// { id: '2', children: [] },
// { id: '3', children: [] },
// ],
// },
// { parentPath: [], index: 0 },
// ],
// [{ id: '2', children: [] }, { parentPath: ['1'], index: 0 }],
// [{ id: '3', children: [] }, { parentPath: ['1'], index: 1 }],
// ]