class Person
attr_accessor :children
attr_reader :name
def initialize(name, children = [])
@name, @children = name, children
end
def all_children
if children.empty?
self
else
arr = []
arr << self
children.each do |child|
arr << child.all_children
end
return arr.flatten
end
end
end
grand_child_1 = Person.new('Matthijs')
grand_child_2 = Person.new('Lisanne')
grand_child_3 = Person.new('Rens')
child_1 = Person.new('Ria', [grand_child_1, grand_child_2])
child_2 = Person.new('Henk', [grand_child_3])
parent = Person.new('Greta', [child_1, child_2])
p parent.all_children.map { |p| p.name }
Refactorings
No refactoring yet !
Dan
October 22, 2008, October 22, 2008 22:10, permalink
This certainly isn't faster or easier to read, but it does cut down the number of lines.
class Person
attr_accessor :children
attr_reader :name
def initialize(name, children = [])
@name, @children = name, children
end
def all_children
children.empty? ? [self] : [self, *children.map{ |c| c.all_children }].flatten
end
end
Adam
October 22, 2008, October 22, 2008 23:05, permalink
require 'enumerator'
class Person
attr_reader :name, :children
def initialize(name, children = [])
@name, @children = name, children
end
def each_descendant(&block)
block.call(self)
children.each { |child| child.each_descendant(&block) }
end
def descendants
Enumerable::Enumerator.new(self, :each_descendant)
end
alias_method :all_children, :descendants
end
# parent.all_children.map { |p| p.name }
halogenandtoast
October 23, 2008, October 23, 2008 00:39, permalink
slightly less bulky, looks like the same result
class Person
attr_reader :name, :children
def initialize(name, children = [])
@name, @children = name, children
end
def all_children
([self] + children.map{|child| child.all_children}).flatten
end
end
Is there a shorter way?