Skip to content

Instantly share code, notes, and snippets.

@edwinmeyer
Last active January 17, 2018 00:31
Show Gist options
  • Save edwinmeyer/f5b209b9f86f8833b495b25cfb8997cf to your computer and use it in GitHub Desktop.
Save edwinmeyer/f5b209b9f86f8833b495b25cfb8997cf to your computer and use it in GitHub Desktop.
Recursively flatten an array by flattening each half of the input array and concatenating the results.
module ArrayTransform
# Recursively flatten an array by flattening each half of the input array and concatenating the results.
# Special cases:
# 1) A zero-length array is returned unchanged
# 2) An array nested inside a single-element array is flattened and returned.
# Terminating condition: An array containing a single non-array-element is returned without modification
def self.flatten(obj)
raise "flatten: Array required; #{obj.class} provided" unless obj.is_a?(Array)
olen = obj.length # because we use it multiple times
return obj if olen==0 # Special case: zero-length array
# Flatten array inside nested single element array,
# or return single element array containing non-array
if olen == 1
return obj[0].is_a?(Array) ? flatten(obj[0]) : obj
end
# head and tail will be at least one element in length
head = obj[0, olen/2] # about half
tail = obj[head.length, olen - head.length] # remainder
flatten(head).concat( flatten(tail) )
end
end
test_cases = [
['non-array object', 1 ],
['empty array', [] ],
['single-obj array', [2] ],
['single-obj nested array', [[2]] ],
['two-obj flat array', [2, 3] ],
['three-obj nested array', [[2], 3, 4] ],
['three-obj nested array', [2, 3, [4]] ],
['four-obj nested array', [2, 3, [[4]]] ],
['complex nested array', [[2, 3], [[4], [5, [6, [[ [7, [[8]]] ]], 9, [10, 11]]]]] ]
]
test_cases.each do |params|
begin
puts "Input: #{params[0]} = #{params[1]}"
puts "Output: #{ArrayTransform.flatten(params[1])}"
rescue Exception => err
puts "The test suite for #{params[0]} raised '#{err}'"
next
end
end
# To run from command line: `ruby flatten_array.rb`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment