Skip to content

Instantly share code, notes, and snippets.

@jamesmartin
Last active August 29, 2015 14:17
Show Gist options
  • Select an option

  • Save jamesmartin/a6fe02accde7f970097a to your computer and use it in GitHub Desktop.

Select an option

Save jamesmartin/a6fe02accde7f970097a to your computer and use it in GitHub Desktop.
Recursively collect all descendants of a Person
require 'rspec'
require 'person'
describe "descendants" do
it "returns all its descendants" do
sonny = Person.new('Sonny')
pa = Person.new('Pa', sonny)
grandpa = Person.new('Grandpa', pa)
expect(Person.all_descendants_of(grandpa).map(&:name)).to eq ['Pa', 'Sonny']
end
it "does not return children that aren't directly related" do
sonny = Person.new('Sonny')
pa = Person.new('Pa', sonny)
ma = Person.new('Ma', sonny)
grandpa = Person.new('Grandpa', pa)
expect(Person.all_descendants_of(grandpa).map(&:name)).to eq ['Pa', 'Sonny']
expect(Person.all_descendants_of(ma).map(&:name)).to eq ['Sonny']
end
it "does not return other people's children" do
sonny = Person.new('Sonny')
pa = Person.new('Pa', sonny)
cousin_donny = Person.new('Donny')
expect(Person.all_descendants_of(cousin_donny).map(&:name)).to eq []
end
end
class Person
attr_reader :name, :children
def initialize(name, children=[])
@name, @children = name, Array(children)
end
def self.all_descendants_of(person, accumulated_children=[])
person.children.each do |child|
accumulated_children << child
Person.all_descendants_of(child, accumulated_children)
end
accumulated_children
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment