Reputation:
So I have the task to reverse a multidimensional array recursively. I can't seem to figure out how.
I have written code that, can reverse a multidimensional array but it is not recursive. Could you guys help me make it recursive?
It should look something like this in the end:
ary = [1,[1,22,[5,7,0],8],2,3]
reverse_rek(ary)
#=> [3, 2, [1, 22, [5, 7, 0], 8], 1]
Here is my attempt:
def reverse_rek(ary)
if not ary.is_a?(Array)
raise ArgumentError, "Dies ist kein Array"
end
reverse_rek_intern(ary)
end
def reverse_rek_intern(ary)
len = ary.length-1
reverse_ary =[]
ary.each_index { |index|
reverse_ary[index] = ary[len-index]
}
return reverse_ary
end
Thank you!
Upvotes: 1
Views: 429
Reputation: 10497
You can also use pop()
along with unshift()
, like this:
def reverse_rek(ary)
if not ary.is_a?(Array)
raise ArgumentError, "Dies ist kein Array"
end
reverse_rek_intern(ary)
end
def reverse_rek_intern(ary)
last = ary.pop
reverse_rek_intern(ary) unless ary.empty?
ary.unshift(last)
end
Or, combining both methods into one:
def reverse_rek(ary)
raise ArgumentError, "Dies ist kein Array" unless ary.is_a?(Array)
last = ary.pop
reverse_rek_intern(ary) unless ary.empty?
ary.unshift(last)
end
Either option will result in the desired output:
ary = [1,[1,22,[5,7,0],8],2,3]
reverse_rek(ary)
#=> [3,2,[1,22,[5,7,0],8],1]
As Peter points out in his answer, i agree that, when the received argument is not an array, its better to return the object itself instead of raising an error.
So, the above method could be updated like this:
def reverse_rek(ary)
return ary unless ary.is_a?(Array)
last = ary.pop
reverse_rek_intern(ary) unless ary.empty?
ary.unshift(last)
end
Upvotes: 0
Reputation: 1912
All the answers so far suffer from simulated polymorphism. Using non OO code to simulate OO behaviour. Checking to see if something is an Array is a dead give away. The following code creates a reverse_rek method for arrays and objects.
class Object
def reverse_rek
self
end
end
class Array
def reverse_rek
reverse.map{|element| element.reverse_rek }
end
end
Here are some examples of the code in action:
irb(main):003:0> [1,2,3].reverse_rek
=> [3, 2, 1]
irb(main):004:0> [1,[2.0,2.1,2.3],3].reverse_rek
=> [3, [2.3, 2.1, 2.0], 1]
irb(main):005:0> [1,[2.0,2.1,2.3],['a','b','c'],3].reverse_rek
=> [3, ["c", "b", "a"], [2.3, 2.1, 2.0], 1]
One difference is this code does not generate errors on non-arrays, they just return themselves. In a sense, they are treated as arrays with one element. and thus not needing to be reversed. Raising errors was not stated as a requirement.
Upvotes: 1
Reputation: 8888
An in-place version
def recursive_reverse!(thing)
case thing
when Array
thing.reverse!
thing.map!{|x| recursive_reverse! x}
else
thing
end
end
The exclamation mark means it modifies the original structure.
And the safe version which doesn't modify the original array or its sub arrays at any level of depth.
def recursive_reverse(thing)
case thing
when Array
thing.reverse.map{|x| recursive_reverse x}
else
thing
end
end
Upvotes: 1