Last active
January 17, 2018 00:31
-
-
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.
This file contains hidden or 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
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