module Tree::Utils::TreeMergeHandler
Provides utility methods to merge two {Tree::TreeNode} based trees. @since 0.9.0
Public Instance Methods
Merge two trees that share the same root node and returns a new tree.
The new tree contains the contents of the merge between other_tree and self. Duplicate nodes (coming from other_tree) will NOT be overwritten in self.
@author Darren Oakley (github.com/dazoakley)
@param [Tree::TreeNode] other_tree The other tree to merge with. @return [Tree::TreeNode] the resulting tree following the merge.
@raise [TypeError] This exception is raised if other_tree is not a
{Tree::TreeNode}.
@raise [ArgumentError] This exception is raised if other_tree does not
have the same root node as self.
# File lib/tree/utils/tree_merge_handler.rb, line 63 def merge(other_tree) check_merge_prerequisites(other_tree) merge_trees(self.root.dup, other_tree.root) end
Merge in another tree (that shares the same root node) into this
tree. Duplicate nodes (coming from other_tree) will NOT be overwritten in self.
@author Darren Oakley (github.com/dazoakley)
@param [Tree::TreeNode] other_tree The other tree to merge with.
@raise [TypeError] This exception is raised if other_tree is not a
{Tree::TreeNode}.
@raise [ArgumentError] This exception is raised if other_tree does not
have the same root node as self.
# File lib/tree/utils/tree_merge_handler.rb, line 81 def merge!(other_tree) check_merge_prerequisites( other_tree ) merge_trees( self.root, other_tree.root ) end
Private Instance Methods
Utility function to check that the conditions for a tree merge are met.
@author Darren Oakley (github.com/dazoakley)
# File lib/tree/utils/tree_merge_handler.rb, line 94 def check_merge_prerequisites(other_tree) unless other_tree.is_a?(Tree::TreeNode) raise TypeError, 'You can only merge in another instance of Tree::TreeNode' end unless self.root.name == other_tree.root.name raise ArgumentError, 'Unable to merge trees as they do not share the same root' end end
Utility function to recursively merge two subtrees.
@author Darren Oakley (github.com/dazoakley)
@param [Tree::TreeNode] tree1 The target tree to merge into. @param [Tree::TreeNode] tree2 The donor tree (that will be merged
into target).
@raise [Tree::TreeNode] The merged tree.
# File lib/tree/utils/tree_merge_handler.rb, line 114 def merge_trees(tree1, tree2) names1 = tree1.has_children? ? tree1.children.map { |child| child.name } : [] names2 = tree2.has_children? ? tree2.children.map { |child| child.name } : [] names_to_merge = names2 - names1 names_to_merge.each do |name| tree1 << tree2[name].detached_subtree_copy end tree1.children.each do |child| merge_trees( child, tree2[child.name] ) unless tree2[child.name].nil? end tree1 end