tags:

views:

150

answers:

6

How do you reverse a string in Ruby? I know about string#reverse. I'm interested in understanding how to write it in Ruby from scratch preferably an in-place solution.

A: 

can't remember where I got this from:

def reverse_string(string) # method reverse_string with parameter 'string'
  loop = string.length # int loop is equal to the string's length
  word = '' # this is what we will use to output the reversed word
  while loop > 0 # while loop is greater than 0, subtract loop by 1 and add the string's index of loop to 'word'
    loop -= 1 # subtract 1 from loop
    word += string[loop] # add the index with the int loop to word
  end # end while loop
  return word # return the reversed word
end # end the method
VoodooChild
Looks like it was written by someone who knew more C than Ruby...
Marc-André Lafortune
A: 

hard to read one liner

def reverse(a)
  (0...(a.length/2)).each {|i| a[i], a[a.length-i-1]=a[a.length-i-1], a[i]}
  return a
end
dagoof
Ouch, my eyes...
Ed Swangren
Not multibyte aware... BTW, the two last `a.length` can be removed
Marc-André Lafortune
he didn't ask for pretty code, guys—this doesn't deserve a -1.
aharon
A: 
str = "something" 
reverse = ""
str.length.times do |i|
reverse.insert(i, str[-1-i].chr)
end
Rishav Rastogi
+1  A: 

There's already an inplace reverse method, called "reverse!":

$ a = "abc"
$ a.reverse!
$ puts a
bca

If you want to do this manually try this (but it will probably not be multibyte-safe, eg UTF-8), and it will be slower:

class String
  def reverse_inplace!
    half_length = self.length / 2
    half_length.times {|i| self[i], self[-i-1] = self[-i-1], self[i] }
  end
end

This swaps every byte from the beginning with every byte from the end until both indexes meet at the center:

$ a = "abcd"
$ a.reverse_inplace!
$ puts a
dcba
hurikhan77
It should be multibyte safe in versions of Ruby where the normal replace is, shouldn't it?
Chuck
Not sure, the linked C source above isn't (at least not the loop). I don't know what the "single_byte_optimizable" does... BTW: The ruby version isn't multibyte safe. I just tried...
hurikhan77
+2  A: 

Here's one way to do it with inject and unshift:

"Hello world".chars.inject([]){|s, c| s.unshift(c)}.join
elektronaut
A: 

The Ruby equivalent of the builtin reverse could look like:

# encoding: utf-8

class String
  def reverse
    each_char.to_a.reverse.join
  end

  def reverse!
    replace reverse
  end
end

str = "Marc-André"
str.reverse!
str # => "érdnA-craM"
str.reverse # => "Marc-André"

Note: this assumes Ruby 1.9, or else require "backports" and set $KCODE for UTF-8,

Marc-André Lafortune