[英]Increment alphabetical string in Ruby on rails
我要解決的任務:
編寫一個接受字符串的程序,將執行轉換並返回它。 對於參數字符串的每個字母,按字母順序將其切換為下一個。 “z”變成“a”,“Z”變成“A”。 案件不受影響。
def rotone(param_1)
a = ""
param_1.each_char do |x|
if x.count("a-zA-Z") > 0
a << x.succ
else
a << x
end
end
a
end
我拿這個:
Input: "AkjhZ zLKIJz , 23y "
Expected Return Value: "BlkiA aMLJKa , 23z "
Return Value: "BlkiAA aaMLJKaa , 23z "
當迭代器找到 'z' 或 'Z' 時,它會增加兩倍 z -> aa 或 Z -> AA
input = "AkjhZ zLKIJz , 23y"
代碼
p input.tr('a-yA-YzZ','b-zB-ZaA')
輸出
"BlkiA aMLJKa , 23z"
您的問題是String#succ (又名String#next )的設計方式在接收者為'z'
或'Z'
時無法滿足您的目的:
'z'.succ #=> 'aa'
'Z'.succ #=> 'AA'
如果您將a << x.succ
a << x.succ[0]
,您將獲得所需的結果。
您可以考慮如下編寫。
def rotone(param_1)
param_1.gsub(/./m) { |c| c.match?(/[a-z]/i) ? c.succ[0] : c }
end
String#gsub的參數是匹配每個字符的正則表達式(因此每個字符都被傳遞到gsub
的塊) 1 。
另請參見String#match? . 正則表達式/[az]/i
匹配作為字符類[az]
中的字符之一的每個字符。 選項i
使匹配大小寫無關,因此也匹配大寫字母。
這是編寫使用兩個定義為常量的哈希的方法的替代方法。
CODE = [*'a'..'z', *'A'..'Z'].each_with_object({}) do |c,h|
h[c] = c.succ[0]
end.tap { |h| h.default_proc = proc { |_h,k| k } }
#=> {"a"=>"b", "b"=>"c",..., "y"=>"z", "z"=>"a",
# "A"=>"B", "B"=>"C",..., "Y"=>"Z", "Z"=>"A"}
DECODE = CODE.invert.tap { |h| h.default_proc = proc { |_h,k| k } }
#=> {"b"=>"a", "c"=>"b", ..., "z"=>"y", "a"=>"z",
# "B"=>"A", "C"=>"B", ..., "Z"=>"Y", "A"=>"Z"}
例如,
CODE['e'] #=> "f"
CODE['Z'] #=> "A"
CODE['?'] #=> "?"
DECODE['f'] #=> "e"
DECODE['A'] #=> "Z"
DECODE['?'] #=> "?"
讓我們嘗試使用帶有示例字符串的gsub
、 CODE
和DECODE
。
str = "The quick brown dog Zelda jumped over the lazy fox Arnie"
rts = str.gsub(/./m, CODE)
#=> "Uif rvjdl cspxo eph Afmeb kvnqfe pwfs uif mbaz gpy Bsojf"
rts.gsub(/./m, DECODE)
#=> "The quick brown dog Zelda jumped over the lazy fox Arnie"
請參閱Hash#merge 、 Object#tap 、 Hash#default_proc= 、 Hash#invert以及將哈希作為可選第二個參數的Sting#gsub形式。
如果h
沒有密鑰k
,則將默認 proc添加到哈希h
會導致h[k]
返回k
。 如果CODE
是在沒有默認過程的情況下定義的,
CODE = [*'a'..'z', *'A'..'Z'].each_with_object({}) { |c,h| h[c] = c.succ[0] }
#=> {"a"=>"b", "b"=>"c",..., "y"=>"z", "z"=>"a",
# "A"=>"B", "B"=>"C",..., "Y"=>"Z", "Z"=>"A"}
gsub
會跳過不是字母的字符:
rts = str.gsub(/./m, CODE)
#=> "UifrvjdlcspxoephAfmebkvnqfepwfsuifmbazgpyBsojf"
如果沒有默認的過程,我們將不得不寫
rts = str.gsub(/./m) { |s| CODE.fetch(s, s) }
#=> "Uif rvjdl cspxo eph Afmeb kvnqfe pwfs uif mbaz gpy Bsojf"
請參閱Hash#fetch 。
1. 正則表達式/./
匹配除行終止符之外的所有字符。 添加選項m
( /./m
) 會導致.
也匹配行終止符。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.