我正在寻找随机将字符串的大小写更改为大写或小写。除了不能保证字符串被更改外,这里还有一个类似的问题。
我目前正在使用:
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')
这有可能会再次出现'Hello
。
我已经看过在.sample
char数组上使用,但是它弄乱了顺序,并且还没有找到一种方法在进行更改后将字符串恢复为原始顺序。
有没有办法保证会发生改变?
有没有办法保证会发生改变?
您可以获得可能更改的字符的索引,例如小写的:
string_to_change = 'Hello'
indices = string_to_change.enum_for(:scan, /[[:lower:]]/).map { $~.begin(0) }
#=> [1, 2, 3, 4]
从此数组中选择1到所有将更改的元素:(顺序无关紧要)
indices_to_be_changed = indices.sample(rand(1..indices.size))
#=> [4, 2]
现在您所要做的就是交换相应字符的大小写:(从上到下,反之亦然)
indices_to_be_changed.each do |i|
string_to_change[i] = string_to_change[i].swapcase
end
string_to_change
#=> "HeLlO"
你能解释一下
{ $~.begin(0) }
在做什么吗?我猜它是从零开始的映射?我已经阅读了一些Ruby文档,并且了解了它在做什么。谢谢,这个解决方案很棒。
那“ HELLO”呢?
@CarySwoveland可以通过检查是否
indices
为空来处理这种情况。我认为至少有一种可能的结果。汤姆,$〜是最后一个正则表达式匹配项的MatchData对象(
$~.class #=> MatchData)
因此,$~.begin(0)
是index处的match数组的元素(这里只有一个)0
。请参见MatchData#begin。也可以编写Regexp.last_match.begin(0)
,这更具有自说明性。Regexp :: last_match。