18

Want to shuffle a string. This is my code: what is wrong about it? Thanks.

>> def string_shuffle(s)
>>   s.split('').shuffle(s.length()).join
>>   return s
>> end
Mike Woodhouse
  • 51,832
  • 12
  • 88
  • 127
Josh Morrison
  • 7,488
  • 25
  • 67
  • 86

6 Answers6

24

If understand you correctly, you want this:

def string_shuffle(s)
  s.split("").shuffle.join
end

string_shuffle("The Ruby language")
=> "ea gu bgTayehRlnu"
kyrylo
  • 1,691
  • 1
  • 15
  • 22
8

return s is both not needed and wrong. Not needed because Ruby returns whatever is executed last and wrong because you are not changing s, you are creating a new string.

Furthermore, you can just add the shuffle method directly to String if you find it useful, but beware of monkeypatching too much.

class String

  def shuffle
    self.split('').shuffle.join
  end
end
Serabe
  • 3,834
  • 19
  • 24
  • 1
    you could put this in a module then apply the module to the string you want to affect, that ways it wont affect other strings in the app and cause unwanted effects. – Joseph Le Brech Aug 10 '11 at 08:13
  • @Joseph, how do you get a module to affect a specific string instance? An example or link would be great. Also, Josh, you may find this [question about monkeypatching](http://stackoverflow.com/questions/394144/what-does-monkey-patching-exactly-mean-in-ruby) useful. – Zabba Aug 10 '11 at 08:17
  • @Zabba http://www.ruby-doc.org/core/classes/Module.html check extend. it monkey patches a variable rather than a class. – Joseph Le Brech Aug 10 '11 at 08:46
  • Besides, explore the differences between including a module and extending it. One common pattern is using the self.included method in the module for extending another one, so it _includes_ a few class methods. – Serabe Aug 10 '11 at 09:07
7

This is faster. 'hello'.chars.shuffle.join

Test yourself:

require 'benchmark'

str = 'Hello' * 100
Benchmark.bm(10) do |x|
  x.report('chars')       { str.chars.shuffle.join }
  x.report('split')       { str.split('').shuffle.join }
  x.report('split regex') { str.split(//).shuffle.join }
end
Hugo
  • 2,402
  • 1
  • 13
  • 4
2

shuffle does not accept (and need) arguments. Use:

 s.split(//).shuffle.to_s
Emiliano Poggi
  • 24,390
  • 8
  • 55
  • 67
1

This will do:

s.chars.shuffle.join

Example:

s = "Hello, World!"
puts s.chars.shuffle.join

Output:

olH!l rWdel,o
kwyntes
  • 1,045
  • 10
  • 27
1

try this

s.split('').shuffle.join
Dnyan Waychal
  • 1,418
  • 11
  • 27