Skip to content

Instantly share code, notes, and snippets.

@marcelorxaviers
Last active June 26, 2017 19:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcelorxaviers/d927afc73648b2d26f07c2e8e253e49a to your computer and use it in GitHub Desktop.
Save marcelorxaviers/d927afc73648b2d26f07c2e8e253e49a to your computer and use it in GitHub Desktop.
Flatten method for array in Ruby
# flatten.rb
module Flatten
extend self
def perform!(array, type = nil)
return [] if type == Array
recursive(array.to_a, type)
rescue
raise "The parameter has to be a #{type || "mixed types"} collection."
end
def integers!(array)
perform!(array, Fixnum)
end
private
def recursive(array, type, flattened = [])
return flattened if array.empty?
head, *tail = array
flatten_head(head, type, flattened)
recursive(tail, type, flattened)
end
def flatten_head(head, type, flattened)
return recursive(head, type, flattened) if head.is_a?(Array)
raise TypeError unless type.nil? || head.is_a?(type)
flattened << head
end
end
# spec/flatten_spec.rb
require_relative "../flatten"
RSpec.describe Flatten do
describe "#perform!" do
context "with nil as param" do
it "returns an empty array" do
expect(Flatten.perform!(nil)).to eq([])
end
end
context "with an empty array as param" do
let(:empty_array) { [] }
it "returns an empty array" do
expect(Flatten.perform!(empty_array)).to eq([])
end
end
context "with an array already flattened as param" do
let(:flattened_array) { [1] }
it "returns the array intact" do
expect(Flatten.perform!(flattened_array)).to eq([1])
end
end
context "with non array / collection object as param" do
it "should raise an error" do
expect{Flatten.perform!("")}.to(
raise_error(RuntimeError, "The parameter has to be a mixed types collection.")
)
end
end
context "with an unflattened array as param" do
let(:unflattened_array) { [1.0, [[[[["2"]]]]], 3, [[[[:four]]]]] }
it "returns a flattened array" do
expect(Flatten.perform!(unflattened_array, nil)).to eq([1.0, "2", 3, :four])
end
end
context "with type as array" do
let(:array_of_arrays) { [[[[[[[[[[]]]]]]]]]] }
it "returns an empty array" do
expect(Flatten.perform!(array_of_arrays, Array)).to eq([])
end
end
end
describe "integers!" do
shared_examples "non integer array" do
it "should raise an error" do
expect{Flatten.integers!(subject)}.to(
raise_error(RuntimeError, "The parameter has to be a Fixnum collection.")
)
end
end
# This is just to ensure that different types of objects will raise the error
[2.1, "", {a: :b}, true, false, :symbol].each do |object|
context "with #{object.class} array as param and type as Fixnum" do
subject { [object] }
it_behaves_like "non integer array"
end
end
context "with an unflattened array as param" do
let(:unflattened_array) { [1, [[[[[2]]]]], 3, [[[[4]]]], [[5]]] }
it "returns a flattened array" do
expect(Flatten.perform!(unflattened_array)).to eq([1, 2, 3, 4, 5])
end
end
end
end
@marcelorxaviers
Copy link
Author

specs_result

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment