Small library for working with nested tree-like data structures.
Each tree-like data structure implements the Tree.Def
protocol which provides implementations for traversing and reducing the nested tree-like data structure. There are default implementations for List
, Tuple
, and Map
.
def deps do
[
{:tree, "~> 0.1.0", github: "seanmor5/tree"}
]
end
Consider the following complex nested data structure:
tree = %{a: {1, [2, 3]}, b: [%{c: {2, 3}, d: [5]}], c: %{d: [6, {7, 8}, 9]}}
Tree
treats values which don't implement the Tree.Def
protocol as leaves, so you can apply arbitrary transformations and reductions to leaves without having to deal with nesting. Most functions you're familiar with in Enum
work in Tree
:
Tree.map(tree, fn x -> x + 1 end)
# %{a: {2, [3, 4]}, b: [%{c: {3, 4}, d: [6]}], c: %{d: [7, {8, 9}, 10]}}
Tree.reduce(tree, 0, fn x, acc -> x + acc end)
# 46
Tree.flat_map(tree, fn x -> x + 1 end)
[2, 3, 4, 3, 4, 6, 7, 8, 9, 10]
If you have multiple nested data structures with the same tree-like structure, you can easily apply zip_with/3
or zip_reduce/4
to transform the trees as a pair:
tree1 = %{a: {1, [2, 3]}, b: [%{c: {2, 3}, d: [5]}], c: %{d: [6, {7, 8}, 9]}}
tree2 = %{a: {9, [10, 11]}, b: [%{c: {12, 13}, d: [14]}], c: %{d: [15, {16, 17}, 18]}}
Tree.zip_with(tree1, tree2, fn x, y -> x + y end)
# %{a: {10, [12, 14]}, b: [%{c: {14, 16}, d: [19]}], c: %{d: [21, {23, 25}, 27]}}
tree1 = %{a: {1, [2, 3]}, b: [%{c: {2, 3}, d: [5]}], c: %{d: [6, {7, 8}, 9]}}
tree2 = %{a: {9, [10, 11]}, b: [%{c: {12, 13}, d: [14]}], c: %{d: [15, {16, 17}, 18]}}
Tree.zip_reduce(tree1, tree2, 0, fn x, y, acc -> x + y + acc end)
# 181