在 rails 上增加 Ruby 中的字母字符串
Increment alphabetical string in Ruby on rails
我要解决的任务:
编写一个接受字符串的程序,将执行转换并 return 它。
对于参数字符串的每个字母,按字母顺序将其切换为下一个字母。
'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 (aka 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?。正则表达式 /[a-z]/i
匹配 字符 class [a-z]
中的每个字符。选项 i
匹配 case-independent,因此大写字母也匹配。
这是另一种编写方法的方法,该方法使用两个定义为常量的哈希值。
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 and the form of Sting#gsub,它将散列作为其可选的第二个参数。
将 默认过程 添加到散列 h
会导致 h[k]
到 return k
if h
没有钥匙 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
) 会导致 .
也匹配行终止符。
我要解决的任务:
编写一个接受字符串的程序,将执行转换并 return 它。 对于参数字符串的每个字母,按字母顺序将其切换为下一个字母。 '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 (aka 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?。正则表达式 /[a-z]/i
匹配 字符 class [a-z]
中的每个字符。选项 i
匹配 case-independent,因此大写字母也匹配。
这是另一种编写方法的方法,该方法使用两个定义为常量的哈希值。
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 and the form of Sting#gsub,它将散列作为其可选的第二个参数。
将 默认过程 添加到散列 h
会导致 h[k]
到 return k
if h
没有钥匙 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
) 会导致 .
也匹配行终止符。