1

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!

3
  • This seems like it's a single dimension array. Try and make you're problem smaller - look at what you've have in the loop - after index=0, you can reverse the the first and the last indices (you need to actually swap now), and now you need to reverse something smaller, an array starting at index=1. Consider also when to stop. Commented Jun 25, 2017 at 9:33
  • no, sorry I did not make this quite clear. I should only swap the "topmost" array. Like in the example Commented Jun 25, 2017 at 11:12
  • I don't understand why it isn't just ary.reverse. Am I missing something? Why should the method be recursive? Commented Jun 26, 2017 at 3:29

3 Answers 3

1

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
Sign up to request clarification or add additional context in comments.

1 Comment

When I try and modify or use the version you have supplied I always get an argument error. Once I use a multidimensional array...
1

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.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.