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 where I took the Dict{String, TreeNode} idea from.
This 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.
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.
You want tree = Dict{String,TreeNode}()
. What you had is just the type, not an instance of that type…
Thanks a lot!
Now I can build me tree with explicit assignments:
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:
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:
TreeNode(w) = (t = new(); t.weight = w)
didn’t work either.
What am I missing?
This TreeNode
returns the weight, not the the node. Make sure t
is the last expression.
function TreeNode(w)
t = TreeNode()
t.weight = w
t
end
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:
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)