class Node
def parent
@parent
end
def ancestor(generation = 0)
node = self
(generation + 1).times { node = node.parent }
node
end
end
Refactorings
No refactoring yet !
Luca
June 14, 2011, June 14, 2011 11:36, permalink
Finding a specific ancestor seems more difficult to me, especially if you don't know the depth of your node in the tree.
I could think to something like:
class Node
attr_accessor :parent, :name
def initialize(name, parent = nil)
self.name = name
self.parent = parent
end
def ancestors(node = self)
[].tap do |ancestors_array|
ancestors_array << node = node.parent while node.parent
end
end
end
progenitor = Node.new('progenitor')
grand_grand_parent = Node.new('grand_grand_parent', progenitor)
grand_parent = Node.new('grand_parent', grand_grand_parent)
parent = Node.new('parent', grand_parent)
node = Node.new('node', parent)
node.ancestors.map(&:name)
# => ["parent", "grand_parent", "grand_grand_parent", "progenitor"]
sparse_node = Node.new('node')
sparse_node.ancestors.map(&:name)
# => []
Adam
June 14, 2011, June 14, 2011 20:50, permalink
Seems like a good place to use an enumerator.
class Node
attr_reader :parent
def ancestors(&block)
if block_given?
if parent
block.call(parent)
parent.ancestors(&block)
end
else
Enumerable::Enumerator.new(self, :ancestors)
end
end
end
Ben Marini
June 14, 2011, June 14, 2011 21:27, permalink
Here's one way
class Node < Struct.new(:name, :parent)
def ancestors
parent.nil? ? [] : [ parent ] + parent.ancestors
end
def to_s
name
end
end
progenitor = Node.new('progenitor')
grand_grand_parent = Node.new('grand_grand_parent', progenitor)
grand_parent = Node.new('grand_parent', grand_grand_parent)
parent = Node.new('parent', grand_parent)
node = Node.new('node', parent)
puts node.ancestors.join(", ")
Let's assume a node on a tree has a direct reference to its parent. I want to be able to traverse the entire ancestry of a node. The current solution I have reeks in my mind. Maybe I'm just overanalyzing it, but I could swear there is a more concise way.
The only given is that @parent refers to the direct parent of the node. Any changes are fair game.