Skip to content

Instantly share code, notes, and snippets.

@jonbarlo
Last active September 27, 2016 23:43
Show Gist options
  • Save jonbarlo/729d4e36aedcd045ff4512b53e99e313 to your computer and use it in GitHub Desktop.
Save jonbarlo/729d4e36aedcd045ff4512b53e99e313 to your computer and use it in GitHub Desktop.
Array Squish (without using Ruby's defined method Array#flatten native method)

Array Squish

Array flatten without using Ruby's native method Array#flatten

Problem description

Write some code, that will flatten an array of arbitrarily nested arrays of integers into a flat array of integers. e.g. [[1,2,[3]],4] -> [1,2,3,4].

Solution

Create an array dinamically by pushing element inside only when the size of array (if present) is lower of equal to depth. Inside the class "ArrayFunctions" you will find a method called "squish" which will receive two parameters: array, depth.

  arr.each_with_object([]) do |element, flattened|
    flattened.push *(element.is_a?(Array) && n != nil && element.size <= n ? squish(element, n) : element)
  end

As you can see we will loop the array until we reach last element inside, and we will push elements on a temporary array only when the element has been "squished" by this i mean that the stop flag will be add elements that have no children (are not an array) or if they do add them only is depth allows it (element.size <= n).

##Source code Sample app and source code can be downloaded here

###Or keep reading to see this sample gist below

    |-- Gemfile
    |-- Gemfile.lock
    |-- Guardfile
    |-- Rakefile
    |-- README.md
    |-- example.rb
    |-- arrayfunctions.rb
    |-- arrayfunctions_unit_test.rb
            
  ###Use instructions
        #just require your helper class
        require './arrayfunctions'
        #there is no need to create an instance
        puts ArrayFunctions.squish([1])

  ###Run test instructions
      ruby arrayfunctions_test.rb
#everything is better defined as a class
class ArrayFunctions
def self.squish(arr, n = nil)
begin
arr.each_with_object([]) do |element, flattened|
flattened.push *(element.is_a?(Array) && n != nil && element.size <= n ? squish(element, n) : element)
end
rescue
#log or treat exception different
#depending on your needs
puts "Unexpected error: code ###"
end
end
end
require 'minitest/autorun'
require './arrayfunctions'
class Tests < MiniTest::Unit::TestCase
#test with default example data provided on http://careers.citrusbyte.com/apply/tPTZOv/Experienced-Software-Developer
def test_with_website_data
array = [[1,2,[3]],4]
#it should be 2
assert_equal array.size, 2
array = ArrayFunctions.squish(array, 1)
#it should be increased by one
assert_equal array.size, 4
end
#one level of nesting flatten
def test_nested_2_level
array = [1,[2, 3]]
#it should be 2
assert_equal array.size, 2
array = ArrayFunctions.squish(array, 1)
#it should be increased by one
assert_equal array.size, 3
end
#two levels of nesting flatten
def test_nested_3_levels
array = [1,[2, 3, [4,5,6]]]
#it should be 2
assert_equal array.size, 2
array = ArrayFunctions.squish(array, 3)
#it should be increased by one
assert_equal array.size, 6
end
end
require './arrayfunctions'
#not required to create an instance of ArrayFunctions
p ArrayFunctions.squish([[1,2,[3]],4],1) # [1, 2, [3], 4]
p ArrayFunctions.squish([1]) # [1]
p ArrayFunctions.squish([[1],2]) # [1, 2]
p ArrayFunctions.squish([[1,[2]]],1) # [1, [2]]
source 'https://rubygems.org'
#gems by groups, env
# A sample Guardfile
# More info at https://github.com/guard/guard#readme
guard :ruby do
watch(%r{(.*)\.rb$})
end
require 'rake'
require 'rake/testtask'
Rake::TestTask.new do |t|
t.pattern = '*.rb'
end
task :default => [:test]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment