Created
February 7, 2018 18:29
-
-
Save fuzzygroup/1f44d4f9f012377f84e0c4bbfb42d006 to your computer and use it in GitHub Desktop.
Flatten array of arbitrarily nested arrays
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
=begin | |
Ruby code that will flatten an array of nested arrays of integers (or whatever) | |
into a flat array of integers. e.g. [[1,2,[3]],4] -> [1,2,3,4]. | |
A tail recursion was adopted so the minimal amount of variables is added to the stack. | |
Usage examples: | |
ArrayTools.flatten([]) | |
ArrayTools.flatten([1,2,3,4,[5,6]]) | |
ArrayTools.flatten([[1],[2],[3],[4],[5,6]]) | |
=end | |
class ArrayTools | |
def self.flatten(array) | |
# abort if it isn;t an array and return nil | |
return nil if !(array.is_a? Array) | |
return self.flatten_pass(array, []) | |
end | |
def self.flatten_pass(array, flat_array) | |
# for each item in array | |
array.each { |x| | |
# if item is not array | |
if !(x.is_a? Array) | |
# push it to flattened array | |
flat_array.push(x) | |
else | |
# else use tail recursion call to flatten | |
flatten_pass(x, flat_array) | |
end | |
} | |
return flat_array | |
end | |
end | |
=begin | |
Since this is single gist, there really wasn't a place to show test coverage so I put it here as a comment | |
require 'rails_helper' | |
RSpec.describe ArrayTools, type: :model do | |
describe ".flatten" do | |
# it should return the same array if nothing needs to be flattened | |
it "should return nil when not given an array" do | |
expect(ArrayTools.flatten([1,2,3])).to eq [1,2,3] | |
end | |
# it should return nil when it does not have an array | |
it "should return [1,2,3] for [1,2,3]" do | |
expect(ArrayTools.flatten(1)).to eq nil | |
end | |
# it should flatten an array | |
it "should return [1,2,3,4,5] for [[1],[2,3],[4],5]" do | |
expect(ArrayTools.flatten([[1],[2,3],[4],5])).to eq [1,2,3,4,5] | |
end | |
end | |
end | |
Example of test output | |
rspec spec/models/array_tools_spec.rb -f d | |
#<Gem::Specification name=sidekiq version=4.2.10> | |
ArrayTools | |
.flatten | |
should return nil when not given an array | |
should return [1,2,3] for [1,2,3] | |
should return [1,2,3,4,5] for [[1],[2,3],[4],5] | |
Finished in 0.04425 seconds (files took 3.42 seconds to load) | |
3 examples, 0 failures | |
=end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment