rose_tree v0.2.0 RoseTree
A rose tree is an n-ary tree in which each node has zero or more children, all of which are themselves rose trees.
Trees are unbalanced and children unordered.
Link to this section Summary
Functions
Add a new child to a tree
Retrieve a list of the values of a node’s immediate children
Fetch a node’s value by traversing a path of indicies through nodes and their children
Convert a map into a rose tree
Determines whether a node is a child of a tree
Map a function over a tree, preserving the tree’s structure (compare
with Enum.map
for rose trees, which maps over a list of node values)
Merge two nodes that have the same value
Create a new, empty rose tree
Initialize a new rose tree with a node value and empty children
Initialize a new rose tree with a node value and children
List all of the possible paths through a tree
Remove the first child from the children of a node
Remove the child at a given index from the children of a node
Extract the node values of a rose tree into a list
Replace the children of a node that matches a given value
Replace the value of every node that matches a given value
Link to this section Types
t() :: %RoseTree{children: [%RoseTree{children: term, node: term}], node: any}
Link to this section Functions
Add a new child to a tree.
If the tree already has children, the new child is added to the front.
If the value of the new child’s node is already present in the tree’s children, then the new child’s children are merged with the existing child’s children.
Examples
iex> hello = RoseTree.new(:hello)
...> world = RoseTree.new(:world)
...> RoseTree.add_child(hello, world)
%RoseTree{node: :hello, children: [
%RoseTree{node: :world, children: []}
]}
iex> hello = RoseTree.new(:hello)
...> world_wide = RoseTree.new(:world, :wide)
...> world_champ = RoseTree.new(:world, :champ)
...> dave = RoseTree.new(:dave)
...> hello
...> |> RoseTree.add_child(world_wide)
...> |> RoseTree.add_child(world_champ)
...> |> RoseTree.add_child(dave)
%RoseTree{children: [
%RoseTree{children: [], node: :dave},
%RoseTree{children: [
%RoseTree{node: :wide, children: []},
%RoseTree{node: :champ, children: []}],
node: :world}],
node: :hello}
Retrieve a list of the values of a node’s immediate children.
Examples
iex> c = RoseTree.new(:c, [:d, :z])
...> tree = RoseTree.new(:a, [:b, c])
...> RoseTree.child_values(tree)
[:b, :c]
iex> tree = RoseTree.new(:hello)
...> RoseTree.child_values(tree)
[]
elem_at(RoseTree.t, [integer]) :: {:ok, any} | {:error, tuple}
Fetch a node’s value by traversing a path of indicies through nodes and their children.
Examples
iex> tree = RoseTree.new(:a, [:b, RoseTree.new(:c, [:d, :z])])
...> RoseTree.elem_at(tree, [])
{:ok, :a}
...> RoseTree.elem_at(tree, [1, 0])
{:ok, :d}
...> RoseTree.elem_at(tree, [1, 2])
{:error, {:rose_tree, :bad_path}}
Convert a map into a rose tree.
Examples
iex> RoseTree.from_map(%{a: [:b]})
{:ok, %RoseTree{node: :a, children: [%RoseTree{node: :b, children: []}]}}
iex> RoseTree.from_map(%{a: %{b: [:c]}})
{:ok, %RoseTree{node: :a, children: [
%RoseTree{node: :b, children: [
%RoseTree{node: :c, children: []}
]}
]}}
is_child?(RoseTree.t, RoseTree.t) :: boolean
Determines whether a node is a child of a tree.
The determination is based on whether the value of the node of the potential child matches a node value in the tree of interest.
Examples
iex> b = RoseTree.new(:b)
...> c = RoseTree.new(:c, [:d, :z])
...> tree = RoseTree.new(:a, [b, c])
...> RoseTree.is_child?(tree, b)
true
...> x = RoseTree.new(:x)
...> RoseTree.is_child?(tree, x)
false
Map a function over a tree, preserving the tree’s structure (compare
with Enum.map
for rose trees, which maps over a list of node values).
Examples
iex> RoseTree.new(0, [1, RoseTree.new(10, [11, 12])])
...> |> RoseTree.map(fn (value) -> value * value end)
%RoseTree{node: 0, children: [
%RoseTree{node: 1, children: []},
%RoseTree{node: 100, children: [
%RoseTree{node: 121, children: []},
%RoseTree{node: 144, children: []}
]}
]}
Merge two nodes that have the same value.
If the sets of children in the two nodes do not share any members, the
children of tree_a
are prepended to tree_b
’s children.
If there are children with the same node value present in both trees,
the children are themselves merged with the child in tree_a
’s children (updated
with the merge of the children of tree_b
’s child) that matched prepended to
the unique children from tree_b
.
Examples
iex> world_wide = RoseTree.new(:world, :wide)
...> world_champ = RoseTree.new(:world, :champ)
...> RoseTree.merge_nodes(world_champ, world_wide)
%RoseTree{
children: [
%RoseTree{children: [], node: :champ},
%RoseTree{children: [], node: :wide}
], node: :world
}
Initialize a new rose tree with a node value and empty children.
Examples
iex> RoseTree.new(:a)
%RoseTree{node: :a, children: []}
Initialize a new rose tree with a node value and children.
Examples
iex> b = RoseTree.new(:b)
...> RoseTree.new(:a, [b, :c])
%RoseTree{node: :a, children: [
%RoseTree{node: :b, children: []},
%RoseTree{node: :c, children: []}
]}
List all of the possible paths through a tree.
Examples
iex> RoseTree.new(:a, [:b, RoseTree.new(:c, [:d, :z])])
...> |> RoseTree.paths()
[[:a, :b], [[:a, :c, :d], [:a, :c, :z]]]
pop_child(RoseTree.t) :: {RoseTree.t, RoseTree.t} | {nil, RoseTree.t}
Remove the first child from the children of a node.
Returns a tuple containing the child that was removed and the modified tree.
Examples
iex> RoseTree.new(:a, [:b, RoseTree.new(:c, [:d, :z])])
...> |> RoseTree.pop_child()
{%RoseTree{node: :b, children: []}, %RoseTree{
node: :a, children: [
%RoseTree{node: :c, children: [
%RoseTree{node: :d, children: []},
%RoseTree{node: :z, children: []}
]}
]
}}
iex> RoseTree.new(:hello)
...> |> RoseTree.pop_child()
{nil, %RoseTree{node: :hello, children: []}}
pop_child_at(RoseTree.t, integer) :: {RoseTree.t, RoseTree.t} | {nil, RoseTree.t}
Remove the child at a given index from the children of a node.
Returns a tuple containing the child that was removed and the modified tree.
Examples
iex> RoseTree.new(:a, [:b, RoseTree.new(:c, [:d, :z])])
...> |> RoseTree.pop_child_at(1)
{%RoseTree{node: :c, children: [
%RoseTree{node: :d, children: []},
%RoseTree{node: :z, children: []}
]}, %RoseTree{node: :a, children: [
%RoseTree{node: :b, children: []}
]}
}
Extract the node values of a rose tree into a list.
Examples
iex> RoseTree.new(:a, [:b, RoseTree.new(:c, [:d, :z])])
...> |> RoseTree.to_list()
[:a, :b, :c, :d, :z]
update_children(RoseTree.t, any, any) :: RoseTree.t
Replace the children of a node that matches a given value.
Note: this will update the value of every match. If there are multiple nodes throughout the tree that match, they will all be updated.
Examples
iex> RoseTree.new(:a, [:b])
...> |> RoseTree.update_children(:a, [RoseTree.new(:c)])
%RoseTree{node: :a, children: [%RoseTree{node: :c, children: []}]}
update_node(RoseTree.t, any, any) :: RoseTree.t
Replace the value of every node that matches a given value.
Note: this will update the value of every match. If there are multiple nodes throughout the tree that match, they will all be updated.
Examples
iex> RoseTree.new(:a, [:b])
...> |> RoseTree.update_node(:a, :hello)
%RoseTree{node: :hello, children: [%RoseTree{node: :b, children: []}]}