# Use Dict to store tree with uninitialized tree nodes

**URL:** https://discourse.julialang.org/t/use-dict-to-store-tree-with-uninitialized-tree-nodes/109895
**Category:** General Usage
**Tags:** dictionary, tree
**Created:** [February 7, 2024, 7:22pm UTC](https://discourse.julialang.org/t/use-dict-to-store-tree-with-uninitialized-tree-nodes/109895 "2024-02-07T19:22:33Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Julia2001](https://avatars.discourse-cdn.com/v4/letter/j/bc79bd/32.png) [@Julia2001](https://discourse.julialang.org/u/Julia2001)
#### Post date: [February 7, 2024, 7:22pm UTC](https://discourse.julialang.org/t/use-dict-to-store-tree-with-uninitialized-tree-nodes/109895/1 "2024-02-07T19:22:33Z")

</div>

I would like to use a Dict with string keys to store a tree. The relations between nodes evolve over time. So they have to be left uninitialized for the most part during initial construction.  
I read about inner and outer constructors but I’m obviously still missing something fundamental here.  
I read also [this](https://stackoverflow.com/questions/36593490/tree-data-structure-in-julia) where I took the Dict{String, TreeNode} idea from.  
[This](https://discourse.julialang.org/t/how-to-create-tree-from-struct/39372) did not help me either. Nevertheless I understand that I can omit the “Nothing” thing.  
In the end the node will have to store an integer in addition.

```julia
mutable struct TreeNode
    parent::Union{Nothing, TreeNode}
    children::Union{Nothing, Vector{TreeNode}}
    TreeNode() = (x = new(); x.parent = nothing; x.children = nothing)
end

tree = Dict{String,TreeNode}

tree["test"] = TreeNode()

```

This give the error message:  
`ERROR: LoadError: MethodError: no method matching setindex!(::Type{Dict{String, TreeNode}}, ::Nothing, ::String)`  
This doesn’t help me understanding what my initial misunderstanding is unfortunately.  
I’m trying to solve AoC 2017/07.

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [February 7, 2024, 7:35pm UTC](https://discourse.julialang.org/t/use-dict-to-store-tree-with-uninitialized-tree-nodes/109895/2 "2024-02-07T19:35:43Z")

</div>

You want `tree = Dict{String,TreeNode}()`. What you had is just the type, not an instance of that type…

---

<div class="post-metadata">

### Author: ![Julia2001](https://avatars.discourse-cdn.com/v4/letter/j/bc79bd/32.png) [@Julia2001](https://discourse.julialang.org/u/Julia2001)
#### Post date: [February 8, 2024, 7:11am UTC](https://discourse.julialang.org/t/use-dict-to-store-tree-with-uninitialized-tree-nodes/109895/3 "2024-02-08T07:11:18Z")

</div>

Thanks a lot!  
Now I can build me tree with explicit assignments:

```julia
mutable struct TreeNode
    weight::Integer
    parent::TreeNode
    children::Vector{TreeNode}
    TreeNode() = new()
end

tree = Dict{String,TreeNode}()

tree["test"] = TreeNode()

tree["test"].weight = 10
display(tree)

```

But how do I add the feature to initialize my payload “weight”?  
My outer constructor attempt:

```julia
mutable struct TreeNode
    weight::Integer
    parent::TreeNode
    children::Vector{TreeNode}
    TreeNode() = new()
end

TreeNode(w) = (t = TreeNode(); t.weight = w)

tree = Dict{String,TreeNode}()

tree["test"] = TreeNode(10)

display(tree)

```

Putting this inside like:

```julia
TreeNode(w) = (t = new(); t.weight = w)

```

didn’t work either.  
What am I missing?

---

<div class="post-metadata">

### Author: ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)
#### Post date: [February 8, 2024, 4:14pm UTC](https://discourse.julialang.org/t/use-dict-to-store-tree-with-uninitialized-tree-nodes/109895/4 "2024-02-08T16:14:39Z")

</div>

> [@Julia2001](#):
>
> `TreeNode(w) = (t = TreeNode(); t.weight = w)`

This `TreeNode` returns the weight, not the the node. Make sure `t` is the last expression.

```julia
function TreeNode(w)
  t = TreeNode()
  t.weight = w
  t
end

```

---

<div class="post-metadata">

### Author: ![Julia2001](https://avatars.discourse-cdn.com/v4/letter/j/bc79bd/32.png) [@Julia2001](https://discourse.julialang.org/u/Julia2001)
#### Post date: [February 8, 2024, 8:03pm UTC](https://discourse.julialang.org/t/use-dict-to-store-tree-with-uninitialized-tree-nodes/109895/5 "2024-02-08T20:03:02Z")

</div>

Thanks to all of you! Both of you have helped but I can only set one “solved” button unfortunately…  
Seeing it now it’s an obvious requirement for a constructor to return the object it is supposed to construct. A concise specification of the new() function is missing in the Julia docs though in my mind. new() is mentioned and one can guess the principle but it’s not spelled out that it actually consumes values for the struct members in order of their appearance. The curly braces syntax is mentioned and this may implicitly include using parameters in round braces but that’s then something I didn’t learn so far…  
This is my solution for now:

```julia
mutable struct TreeNode
    weight::Integer
    parent::TreeNode
    children::Vector{TreeNode}
    TreeNode(w) = new(w)
    TreeNode() = new()
end

tree = Dict{String,TreeNode}()

tree["test"] = TreeNode()
tree["test2"] = TreeNode(20)

tree["test"].weight = 10
tree["test2"].children = [tree["test"]]
display(tree)

```
