Warm tip: This article is reproduced from stackoverflow.com, please click
ruby

Randomly change of characters in a string in Ruby

发布于 2020-03-29 21:03:50

I'm looking to randomly change the case of a string to upcase or downcase. There is a similar question on here for it except it doesn't guarantee that the string gets changed.

I am currently using:

def random_case_changes(string_to_change: string, change_case: 'downcase')
  raise ArgumentError, "Param is #{string_to_change.class}, not a string" unless string_to_change.is_a? String

  string_to_change.chars.map { |char| (rand 0..2).zero? ? char : char.send(change_case) }.join
end

random_case_changes(string_to_change: 'Hello', change_case: 'upcase')

There is a chance that this will just return 'Hello.

I've looked at using .sample on the array of chars, but it jumbles the order and I haven't found a way to put the string back into it's original order after a change has been made.

Is there a way to guarantee that a change will take place?

Questioner
Tom
Viewed
75
Stefan 2020-01-31 16:16

Is there a way to guarantee that a change will take place?

You could get the indices of the character that could change, e.g. the lowercase ones:

string_to_change = 'Hello'

indices = string_to_change.enum_for(:scan, /[[:lower:]]/).map { $~.begin(0) }
#=> [1, 2, 3, 4]

And out of this array pick between 1 and all elements that will change: (the order doesn't matter)

indices_to_be_changed = indices.sample(rand(1..indices.size))
#=> [4, 2]

Now all you have to do is swap the case of the corresponding characters: (upper to lower or vice-versa)

indices_to_be_changed.each do |i|
  string_to_change[i] = string_to_change[i].swapcase
end

string_to_change
#=> "HeLlO"