簡體   English   中英

在 Ruby on rails 中增加字母字符串

[英]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['?'] #=> "?"

讓我們嘗試使用帶有示例字符串的gsubCODEDECODE

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#mergeObject#tapHash#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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM