Ruby中随机修改字符串大小写并确保产生变更的实现方案
Answer
Great question! The issue with your current code is that there’s a small but real chance every character randomly skips the case change, leaving you with the original string. To fix this, we need to guarantee at least one character is modified—while also handling edge cases where no changes are possible (like trying to upcase an all-uppercase string).
Here’s a revised solution that addresses both problems:
def random_case_changes(string_to_change:, change_case:) # Validate input is a string raise ArgumentError, "Param is #{string_to_change.class}, not a string" unless string_to_change.is_a?(String) # Ensure change_case is one of the valid options unless %w[upcase downcase].include?(change_case) raise ArgumentError, "change_case must be either 'upcase' or 'downcase'" end chars = string_to_change.chars # Find indices where changing case will actually alter the character eligible_indices = chars.each_index.select do |i| chars[i].send(change_case) != chars[i] end # If no characters can be changed, we can't fulfill the requirement if eligible_indices.empty? raise ArgumentError, "Cannot apply #{change_case} to any character in '#{string_to_change}'" end # Pick a random eligible index to force a change (guarantees at least one modification) forced_index = eligible_indices.sample # Process each character: force change on the selected index, random for others modified_chars = chars.each_with_index.map do |char, i| if i == forced_index char.send(change_case) else rand(0..2).zero? ? char : char.send(change_case) end end modified_chars.join end
How this works:
- Input Validation: We first check that the input is a string and that
change_caseis either'upcase'or'downcase'(prevents invalid method calls later). - Eligible Character Check: We identify all positions where changing the case will actually modify the character (e.g., a lowercase 'e' can be upcased, but an uppercase 'H' can’t be upcased further).
- Edge Case Handling: If no eligible characters exist (like an all-uppercase string being passed to
upcase), we raise an error because we can’t make any changes to meet the requirement. - Force At Least One Change: We randomly select one eligible index and guarantee that character is changed. For all other characters, we keep your original random logic (1/3 chance to stay the same, 2/3 chance to change case).
Example Usage:
random_case_changes(string_to_change: 'Hello', change_case: 'upcase') # Will never return 'Hello'—at least one character will be upcased (e.g., 'HEllo', 'hEllO', etc.)
This approach is efficient (no looping to re-generate the string) and ensures you always get a modified result when possible.
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

