Last active
June 26, 2017 19:57
-
-
Save marcelorxaviers/d927afc73648b2d26f07c2e8e253e49a to your computer and use it in GitHub Desktop.
Flatten method for array in Ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 |
Author
marcelorxaviers
commented
Jun 26, 2017
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment