def vowel(str) result = "" new = str.split(" ") i = 0 while i < new.length if new[i] == "a" i = i + 1 elsif new[i] != "a" result = new[i] + result end i = i + 1 end return resultend
当我运行代码时,它返回我输入的确切字符串(str).例如,如果我输入“apple”,则返回“apple”.
这是我的原始代码.它有相同的结果.
def vowel(str) result = "" new = str.split(" ") i = 0 while i < new.length if new[i] != "a" result = new[i] + result end i = i + 1 end return resultend
我需要知道使用这种方法我做错了什么.我究竟做错了什么?
解决方法 找到错误通过在IRB中执行方法代码,让我们看看原始代码有什么问题:
$irbirb(main):001:0> str = "apple"#=> "apple"irb(main):002:0> new = str.split(" ")#=> ["apple"]
答对了! [“apple”]不是预期的结果. documentation for String#split
说什么?
split(pattern=$;,[limit]) → anArraydivIDes str into substrings based on a delimiter,returning an array of these substrings.
If pattern is a
String
,then its contents are used as the delimiter when splitting str. If pattern is a single space,str is split on whitespace,with leading whitespace and runs of contiguous whitespace characters ignored.
我们的模式是单个空格,因此split返回一个单词数组.这绝对不是我们想要的.为了获得所需的结果,即一个字符数组,我们可以传递一个空字符串作为模式:
irb(main):003:0> new = str.split("")#=> ["a","p","l","e"]
“拆分空字符串”感觉有点Hacky,确实有另一种方法完全符合我们的要求:String#chars
chars → an_arrayReturns an array of characters in str. This is a shorthand for
str.each_char.to_a
.
试一试吧:
irb(main):004:0> new = str.chars#=> ["a","e"]
完美,就像广告一样.
另一个错误
使用新方法,您的代码仍然不会返回预期的结果(我将从现在开始省略IRB提示):
vowel("apple") #=> "elpp"
这是因为
result = new[i] + result
将字符添加到结果字符串中.要追加它,我们必须写
result = result + new[i]
或者甚至更好,使用追加方法String#<<
:
result << new[i]
我们来试试吧:
def vowel(str) result = "" new = str.chars i = 0 while i < new.length if new[i] != "a" result << new[i] end i = i + 1 end return resultendvowel("apple") #=> "pple"
看起来不错,“a”已被删除(“e”仍在那里,因为你只检查“a”).
现在进行一些重构.
删除显式循环计数器
与使用显式循环计数器的while循环不同,使用类似Integer#times
的东西更为惯用:
new.length.times do |i| # ...end
或Range#each
:
(0...new.length).each do |i| # ...end
或Array#each_index
:
new.each_index do |i| # ...end
让我们应用后者:
def vowel(str) result = "" new = str.chars new.each_index do |i| if new[i] != "a" result << new[i] end end return resultend
好多了.我们不必担心初始化循环计数器(i = 0)或将其递增(i = i 1).
避免字符索引
而不是通过each_index迭代字符索引:
new.each_index do |i| if new[i] != "a" result << new[i] endend
我们可以使用Array#each
迭代字符本身:
new.each do |char| if char != "a" result << char endend
删除字符数组
我们甚至不必创建新的字符数组.还记得chars的文档吗?
This is a shorthand for
str.each_char.to_a
.
String#each_char
将每个字符传递给给定的块:
def vowel(str) result = "" str.each_char do |char| if char != "a" result << char end end return resultend
return关键字是可选的.我们可以只写结果而不是返回结果,因为方法的return value是被评估的最后一个表达式.
删除显式字符串
Ruby甚至允许您使用Enumerator#with_object
将对象传递到循环中,从而消除显式结果字符串:
def vowel(str) str.each_char.with_object("") do |char,result| if char != "a" result << char end endend
with_object将“”作为结果传递给块并返回它(在块中附加了字符之后).它也是该方法中的最后一个表达式,即其返回值.
你也可以使用if
as a modifier,即:
result << char if char != "a"
备择方案
有许多不同的方法可以从字符串中删除字符.
另一种方法是使用Enumerable#reject
过滤掉元音字符(它返回包含剩余字符的新数组),然后使用join
过滤掉字符(有关删除所有元音的版本,请参阅Nathan’s answer):
def vowel(str) str.each_char.reject { |char| char == "a" }.joinend
但是对于字符串 *** 作这样的基本 *** 作,Ruby通常已经提供了一种方法.查看内置替代品的其他答案:
> str.delete(‘aeIoUAEIoU’),如Gagan Gami’s answer所示
> str.tr(‘aeIoUAEIoU’,”),如Cary Swoveland’s answer所示
> str.gsub(/ [aeIoU] / i,如Avinash Raj’s answer所示
命名的东西
Cary Swoveland pointed out元音不是你方法的最佳名称.仔细选择方法,变量和类的名称.希望有一个简短而简洁的方法名称,但它也应该传达其意图.
元音(str)显然与元音有关,但目前尚不清楚它是什么.是否从str返回元音或所有元音?它检查str是元音还是包含元音?
remove_vowels或delete_vowels可能是更好的选择.
变量相同:new是一个字符数组.为什么不称它为字符(如果空间有问题,则称为字符)?
底线:阅读精细手册并了解您的工具.大多数情况下,IRB会话就是调试代码所需的全部内容.
总结以上是内存溢出为你收集整理的ruby – 取出一根弦并将元音取下来全部内容,希望文章能够帮你解决ruby – 取出一根弦并将元音取下来所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)