I would suggest using RubyTree for this, rather than a data structure. There are several advantages:
- Some of the queries you may need to do have already been implemented efficiently
- The naming conventions match your domain (parent/grandparent/siblings/children etc)
- It will shorten your code considerably and make it easier to read
- There are built-in ways to traverse and print the tree
Here's an excerpt from the documentation, which will help you get a feel for it:
require 'tree'
# ..... Create the root node first. Note that every node has a name and an optional content payload.
root_node = Tree::TreeNode.new("ROOT", "Root Content")
root_node.print_tree
# ..... Now insert the child nodes. Note that you can "chain" the child insertions for a given path to any depth.
root_node << Tree::TreeNode.new("CHILD1", "Child1 Content") << Tree::TreeNode.new("GRANDCHILD1", "GrandChild1 Content")
root_node << Tree::TreeNode.new("CHILD2", "Child2 Content")
# ..... Lets print the representation to stdout. This is primarily used for debugging purposes.
root_node.print_tree
# ..... Lets directly access children and grandchildren of the root. The can be "chained" for a given path to any depth.
child1 = root_node["CHILD1"]
grand_child1 = root_node["CHILD1"]["GRANDCHILD1"]
# ..... Now lets retrieve siblings of the current node as an array.
siblings_of_child1 = child1.siblings
# ..... Lets retrieve immediate children of the root node as an array.
children_of_root = root_node.children
Note that the examples show the node content as a string, but you can put any object there. You may want to create a value object to hold all your metadata.
class FamilyMember
attr_accessor :name :last_name, :maiden_name, :birth_date, :etc
end
Hopefully after doing all of this your code will be more like uncle_bob.children.first.birth_date -- very readable.
TreeNode.new ('some_key', 'some_value or some_content'). In the documentation I have not seen multiple values. To all my values that I need, be a good idea to put them all on the part ofsome_contentas one long string and then make split.