Skip to content

Instantly share code, notes, and snippets.

@stedwick
Last active June 15, 2018 23:27
Show Gist options
  • Save stedwick/2b3a61b80b3ecca6e1894607ddfa02c1 to your computer and use it in GitHub Desktop.
Save stedwick/2b3a61b80b3ecca6e1894607ddfa02c1 to your computer and use it in GitHub Desktop.
Citrusbyte code sample: Write some code, that will flatten an array of arbitrarily nested arrays of integers into a flat array of integers. e.g. [[1,2,[3]],4] -> [1,2,3,4].
#!/usr/bin/env ruby
puts "Hello Citrusbyte!"
puts
puts "Run this file with `ruby phils_flatten.rb -v` and it will automatically run the Minitests."
puts "Also, generate the rdoc with `rdoc phils_flatten.rb` and open ./doc/PhilsFlatten.html."
puts
# Include this module in the Array class to add the method phils_flatten to arrays, which recursively flattens them.
#
# class Array
# include PhilsFlatten
# end
#
module PhilsFlatten
# I strongly object to not being allowed to cheat during this exercise =P
# [[1,2,[3]],4].phils_flatten_cheating == [[1,2,[3]],4].flatten
#
def phils_flatten_cheating
self.flatten
end
# This method flattens any enumerable object that responds to the method "each", such as Array.
# [[1,2,[3]],4].phils_flatten == [1,2,3,4]
#
# my_array.phils_flatten iterates over each of its elements, and then either returns them in order, or recursively calls phils_flatten on elements that themselves need to be flattened.
def phils_flatten
flattened = []
self.each do | item |
if item.respond_to? :phils_flatten
# I'm purposefully avoiding the Ruby-ism "array += [other_array]".
item.phils_flatten.each do | sub_item |
flattened << sub_item
end
else
flattened << item
end
end
return flattened
end
end
# This is the Ruby standard library Array.
class Array # :nodoc:
# Include the PhilsFlatten module into the Array class to add phils_flatten to Array objects.
include PhilsFlatten
end
# Here we begin testing PhilsFlatten. First require minitest.
require "minitest/autorun"
puts "Testing that [[1,2,[3]],4].phils_flatten == [1,2,3,4]"
puts "Testing that [\"one\", [[2, \"quick brown fox\"]], [1, Time.now, [3] ], 4].phils_flatten == [\"one\", 2, \"quick brown fox\", 1, Time.now, 3, 4]"
puts "Testing that phils_flatten == flatten for @test_array"
puts "Testing that phils_flatten == flatten for @test_array_two"
puts
# This class tests the PhilsFlatten module on Array.
class TestPhilsFlatten < Minitest::Test
# Sets up two test arrays, a simple one and a complex one.
def setup
@current_time = Time.now
@test_array = [[1,2,[3]],4]
@test_array_two = ["one", [[2, "quick brown fox"]], [1, @current_time, [3] ], 4]
end
# Test that a nested array of integers flattens properly.
# [[1,2,[3]],4].phils_flatten == [1,2,3,4]
def test_that_phils_flatten_works_on_test_array
assert_equal @test_array.phils_flatten, [1, 2, 3, 4]
end
# Testing that complicated nested arrays of multiple objects flattens properly.
# ["one", [[2, "quick brown fox"]], [1, Time.now, [3] ], 4].phils_flatten == ["one", 2, "quick brown fox", 1, Time.now, 3, 4]
def test_that_phils_flatten_works_on_test_array_two
assert_equal @test_array_two.phils_flatten, ["one", 2, "quick brown fox", 1, @current_time, 3, 4]
end
# Testing that +phils_flatten+ and +flatten+ are the same for +test_array+.
# @test_array.phils_flatten == @test_array.flatten
def test_that_phils_flatten_equals_builtin_flatten_on_test_array
assert_equal @test_array.phils_flatten, @test_array.flatten
end
# Testing that +phils_flatten+ and +flatten+ are the same for +test_array_two+.
# @test_array_two.phils_flatten == @test_array_two.flatten
def test_that_phils_flatten_equals_builtin_flatten_on_test_array_two
assert_equal @test_array_two.phils_flatten, @test_array_two.flatten
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment