Skip to content

Instantly share code, notes, and snippets.

@fuzzygroup
Created February 7, 2018 18:29
Show Gist options
  • Save fuzzygroup/1f44d4f9f012377f84e0c4bbfb42d006 to your computer and use it in GitHub Desktop.
Save fuzzygroup/1f44d4f9f012377f84e0c4bbfb42d006 to your computer and use it in GitHub Desktop.
Flatten array of arbitrarily nested arrays
=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