使用Ruby将字符串中的元音大写

使用Ruby将字符串中的元音大写,ruby,string,Ruby,String,我有一个方法,将字符串作为参数,用字母表中的下一个字母替换每个字母,然后将每个元音大写。我已经让这两个单独工作(替换和资本化),但在这一点上,我只是不知道如何使他们一起工作 def LetterChanges(str) new_str = str.downcase.split("") new_str.each do |x| x.next! end new_str.to_s.tr!('aeiou','AEIOU') return new_st

我有一个方法,将字符串作为参数,用字母表中的下一个字母替换每个字母,然后将每个元音大写。我已经让这两个单独工作(替换和资本化),但在这一点上,我只是不知道如何使他们一起工作

def LetterChanges(str)
    new_str = str.downcase.split("")
    new_str.each do |x|
        x.next!
    end
    new_str.to_s.tr!('aeiou','AEIOU')
    return new_str.join("")
end

LetterChanges("abcdef")

new-str.to-s
不会存储在任何位置。它不会影响原始数组

return new_str.join("").tr('aeiou', 'AEIOU')

这会将数组转换回字符串,您可以对其进行操作并将其返回。

new\u str.
不会存储在任何位置。它不会影响原始数组

return new_str.join("").tr('aeiou', 'AEIOU')
2.1.0 :012 > 'abcdef'.split('').map(&:next).join.tr('aeiou', 'AEIOU')
 => "bcdEfg"
这将把数组转换回字符串,您可以对其进行操作并返回它

2.1.0 :012 > 'abcdef'.split('').map(&:next).join.tr('aeiou', 'AEIOU')
 => "bcdEfg"
当然,我不建议在一行中这样做。但是,为了让您对这些方法如何组合感到困惑,这里有一个可行的解决方案。当有疑问时,使用IRB调用每个方法并观察Ruby如何响应。这将帮助您找出代码的故障位置

实际上,我会将其分解为多种方法。一种方法做的事情太多了。而且,正如您所发现的,发现bug(和测试)也要困难得多

def rotate(string)
  string.split('').map(&:next).join
end

def capitalize_vowels(string)
  string.tr('aeiou', 'AEIOU')
end
当然,我不建议在一行中这样做。但是,为了让您对这些方法如何组合感到困惑,这里有一个可行的解决方案。当有疑问时,使用IRB调用每个方法并观察Ruby如何响应。这将帮助您找出代码的故障位置

实际上,我会将其分解为多种方法。一种方法做的事情太多了。而且,正如您所发现的,发现bug(和测试)也要困难得多

def rotate(string)
  string.split('').map(&:next).join
end

def capitalize_vowels(string)
  string.tr('aeiou', 'AEIOU')
end

这可以通过
gsub
解决

"abcdef".gsub(/./){|char| char.next}.gsub(/[aeiou]/){|vowel| vowel.upcase}
#=> "bcdEfg" 
所以这个方法可以

def letter_changes_gsub(str)
  str.gsub(/./){|char| char.next}.gsub(/[aeiou]/){|vowel| vowel.upcase}
end

这比使用阵列更快、更简单

这可以通过
gsub
解决

"abcdef".gsub(/./){|char| char.next}.gsub(/[aeiou]/){|vowel| vowel.upcase}
#=> "bcdEfg" 
所以这个方法可以

def letter_changes_gsub(str)
  str.gsub(/./){|char| char.next}.gsub(/[aeiou]/){|vowel| vowel.upcase}
end

这比使用阵列更快、更简单

其他答案已经向您展示了如何组合代码的两个部分。但是有一个:在
“z”
之后是“aa”:

您可以添加
if
语句来处理此情况:

str.chars.map do |char|
  if char == 'z'
    'a'
  else
    char.next
  end
end.join
或:

但有一种更简单的方法:让我们执行整个替换:

str.downcase.tr('a-z', 'bcdEfghIjklmnOpqrstUvwxyzA')
或稍短一点:

str.downcase.tr('a-z', 'bcdEfghIjk-nOp-tUv-zA')

其他答案已经向您展示了如何组合代码的两个部分。但是有一个:在
“z”
之后是“aa”:

您可以添加
if
语句来处理此情况:

str.chars.map do |char|
  if char == 'z'
    'a'
  else
    char.next
  end
end.join
或:

但有一种更简单的方法:让我们执行整个替换:

str.downcase.tr('a-z', 'bcdEfghIjklmnOpqrstUvwxyzA')
或稍短一点:

str.downcase.tr('a-z', 'bcdEfghIjk-nOp-tUv-zA')
那么:

def string_thing(string)
    string.downcase.tr('abcdefghijklmnopqrstuvwxyz','bcdEfghIjklmnOpqrstUvwxyzA')
end
#tr
将第一个参数中的每个字符替换为第二个参数中相应的字符

那么:

def string_thing(string)
    string.downcase.tr('abcdefghijklmnopqrstuvwxyz','bcdEfghIjklmnOpqrstUvwxyzA')
end

#tr
将第一个参数中的每个字符替换为第二个参数中相应的字符

这可以通过组合使用
gsub
tr
来实现:

“abcdef”.gsub(/[A-z]/){| char | char.next}.tr('aeiou','aeiou'))
#=>“bcdEfg”
“有趣的时刻!”.gsub(/[A-z]/){| char | char.next}.tr('aeiou','aeiou'))
#=>“GvO Ujnft!”

这可以通过组合
gsub
tr
来实现:

“abcdef”.gsub(/[A-z]/){| char | char.next}.tr('aeiou','aeiou'))
#=>“bcdEfg”
“有趣的时刻!”.gsub(/[A-z]/){| char | char.next}.tr('aeiou','aeiou'))
#=>“GvO Ujnft!”

或只是
str.downcase.split(“”).map(&:next).join.tr('aeiou','aeiou')
。多谢各位!这对我来说现在更有意义了。还有@suslov,下一个之前的&:是什么?我已经在示例代码中看到了这一点,但很难研究它到底起什么作用。我以前见过并使用过
inject(:*)
,这似乎与此类似。再次感谢。非常干净优雅的解决方案。:)@Dwipple:不客气,关于
&
速记有很好的解释。
join(“”
相当于
join
(即,除非您更改
$,
)或只更改
str.downcase.split(“”).map(&:next.join.tr('aeiou','aeiou')
)。多谢各位!这对我来说现在更有意义了。还有@suslov,下一个之前的&:是什么?我已经在示例代码中看到了这一点,但很难研究它到底起什么作用。我以前见过并使用过
inject(:*)
,这似乎与此类似。再次感谢。非常干净优雅的解决方案。:)@Dwipple:不客气,关于
&
速记有很好的解释。
join(“”
相当于
join
(也就是说,除非您更改
$,
),为什么我经常看到(原文如此)“您可以用下面的一行代码来完成”。这就好比一个服务员给我端上一盘食物,然后评论道:“这是你的晚餐。”服务员是否认为我可能没有意识到我要吃它,或者想清楚这是给我的,而不是给另一位顾客的?有些事情不是很明显吗?@CarySwoveland看起来这是一个附加条件,你不应该真的做一行。为什么我经常看到(原文如此)“你可以做下面的一行”。这就好比一个服务员给我端上一盘食物,然后评论道:“这是你的晚餐。”服务员是否认为我可能没有意识到我要吃它,或者想清楚这是给我的,而不是给另一位顾客的?有些事情不是很明显吗?@caryswovel而且看起来这是一个限制条件,你不应该真正把它作为一行。在
“z”
之后是什么字母?你应该使用
.chars
而不是
。split(“”)
后面是什么字母
“z”
?你应该使用
.chars
而不是
。split(“”)