Skip to content

Instantly share code, notes, and snippets.

@bessey
Created December 22, 2018 19:49
Show Gist options
  • Save bessey/438e68b7055f3a2862498185e50a3f78 to your computer and use it in GitHub Desktop.
Save bessey/438e68b7055f3a2862498185e50a3f78 to your computer and use it in GitHub Desktop.
### IMPLEMENTATION ###
# Flattens an arbitrarily nested enumerable of enumerables.
# Works for Arrays of Integers, and more.
class EnumerableFlattener
attr_reader :array
def initialize(array)
@array = array
end
def call
array.inject([]) do |output, array_or_item|
if array_or_item.respond_to?(:each)
flattened = self.class.new(array_or_item).call
output.push(*flattened)
else
output.push(array_or_item)
end
end
end
end
# Optional core extension, depending on your feelings about 🐒-patching
class Array
def deep_flatten
EnumerableFlattener.new(self).call
end
end
### SPECS ###
# Usage:
# ruby -Ilib:test enumerable_flattener.rb
require "minitest/autorun"
require "set"
describe EnumerableFlattener do
describe "call" do
describe "with an array of arbitrarily nested empty arrays" do
it "flattens to an empty array" do
flatten([[],[[],[[]],[]]]).must_equal []
end
end
describe "with an array of arbitrarily nested arrays of integers" do
it "flattens into an array of integers" do
flatten([[[[[1]]]]]).must_equal [1]
flatten([[1,2,[3]],4]).must_equal [1,2,3,4]
flatten([[1,2,[3, [4, 5], 6]],7]).must_equal [1,2,3,4,5,6,7]
end
end
describe "with an array of arbitrarily nested enumerables of non-enumerables" do
it "flattens into an array of non-enumerables" do
input = Set.new([1, [2, "buckle my shoe"], Set.new([3, 4]), Set.new([5]), 6])
flatten(input).must_equal [1, 2, "buckle my shoe", 3, 4, 5, 6]
end
end
end
describe "core extension Array#deep_flatten" do
describe "with an array of arbitrarily nested arrays of integers" do
it "flattens into an array of integers" do
[[1,2,[3]],4].deep_flatten.must_equal [1,2,3,4]
end
end
end
def flatten(array)
EnumerableFlattener.new(array).call
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment