我正在尝试编写一个带有字符串的函数,并在删除所有元音后返回它.以下是我的代码.
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 result
end
Run Code Online (Sandbox Code Playgroud)
当我运行代码时,它返回我为(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 result
end
Run Code Online (Sandbox Code Playgroud)
我需要知道使用这种方法我做错了什么.我究竟做错了什么?
通过在IRB中执行方法代码,让我们看看原始代码有什么问题:
$ irb
irb(main):001:0> str = "apple"
#=> "apple"
irb(main):002:0> new = str.split(" ")
#=> ["apple"]
Run Code Online (Sandbox Code Playgroud)
答对了!["apple"]不是预期的结果.这些文件String#split说的是什么?
split(pattern = $;,[limit])→anArray
将str分为基于分隔符的子字符串,返回这些子字符串的数组.
如果pattern是a
String,则在拆分str时将其内容用作分隔符.如果pattern是单个空格,则str在空格上拆分,前导空格和连续空格字符的运行被忽略.
我们的模式是单个空格,因此split返回一个单词数组.这绝对不是我们想要的.为了获得所需的结果,即一个字符数组,我们可以传递一个空字符串作为模式:
irb(main):003:0> new = str.split("")
#=> ["a", "p", "p", "l", "e"]
Run Code Online (Sandbox Code Playgroud)
"拆分空字符串"感觉有点hacky,确实还有另一种方法可以完全符合我们的要求: String#chars
chars→an_array
返回str中的字符数组.这是一个简写
str.each_char.to_a.
试一试吧:
irb(main):004:0> new = str.chars
#=> ["a", "p", "p", "l", "e"]
Run Code Online (Sandbox Code Playgroud)
完美,就像广告一样.
使用新方法,您的代码仍然不会返回预期的结果(我将从现在开始省略IRB提示):
vowel("apple") #=> "elpp"
Run Code Online (Sandbox Code Playgroud)
这是因为
result = new[i] + result
Run Code Online (Sandbox Code Playgroud)
将字符预先添加到result字符串中.要追加它,我们必须写
result = result + new[i]
Run Code Online (Sandbox Code Playgroud)
或者甚至更好,使用append方法String#<<:
result << new[i]
Run Code Online (Sandbox Code Playgroud)
我们来试试吧:
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 result
end
vowel("apple") #=> "pple"
Run Code Online (Sandbox Code Playgroud)
看起来很好,"a"已被删除("e"仍然存在,因为你只检查"a").
现在进行一些重构.
而不是while具有显式循环计数器的循环,使用类似的东西更加惯用Integer#times:
new.length.times do |i|
# ...
end
Run Code Online (Sandbox Code Playgroud)
或者Range#each:
(0...new.length).each do |i|
# ...
end
Run Code Online (Sandbox Code Playgroud)
new.each_index do |i|
# ...
end
Run Code Online (Sandbox Code Playgroud)
让我们应用后者:
def vowel(str)
result = ""
new = str.chars
new.each_index do |i|
if new[i] != "a"
result << new[i]
end
end
return result
end
Run Code Online (Sandbox Code Playgroud)
好多了.我们不必担心初始化循环计数器(i = 0)或递增它(i = i + 1).
而不是通过以下方式迭代字符索引each_index:
new.each_index do |i|
if new[i] != "a"
result << new[i]
end
end
Run Code Online (Sandbox Code Playgroud)
我们可以使用Array#each以下方法迭代字符本身:
new.each do |char|
if char != "a"
result << char
end
end
Run Code Online (Sandbox Code Playgroud)
我们甚至不必创建new字符数组.还记得文档chars吗?
这是一个简写
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 result
end
Run Code Online (Sandbox Code Playgroud)
该return关键字是可选的.我们可以写result而不是return result,因为方法的返回值是被评估的最后一个表达式.
Ruby甚至允许您使用对象传递对象Enumerator#with_object,从而消除显式result字符串:
def vowel(str)
str.each_char.with_object("") do |char, result|
if char != "a"
result << char
end
end
end
Run Code Online (Sandbox Code Playgroud)
with_object传递""到块中result并返回它(在块中附加字符之后).它也是方法中的最后一个表达式,即它的返回值.
您还可以使用if修饰符,即:
result << char if char != "a"
Run Code Online (Sandbox Code Playgroud)
有许多不同的方法可以从字符串中删除字符.
另一种方法是使用Enumerable#reject(它返回一个包含剩余字符的新数组)和字符过滤掉元音字符join(请参阅Nathan的答案,删除所有元音的版本):
def vowel(str)
str.each_char.reject { |char| char == "a" }.join
end
Run Code Online (Sandbox Code Playgroud)
但是对于字符串操作这样的基本操作,Ruby通常已经提供了一种方法.查看内置替代品的其他答案:
str.delete('aeiouAEIOU')正如Gagan Gami的回答所示str.tr('aeiouAEIOU', '')如Cary Swoveland的回答所示str.gsub(/[aeiou]/i, '')如Avinash Raj的回答所示Cary Swoveland指出,这vowel不是你方法的最佳名称.仔细选择方法,变量和类的名称.希望有一个简短而简洁的方法名称,但它也应该传达其意图.
vowel(str)显然与元音有关,但目前尚不清楚它是什么.它是否会返回元音或所有元音str?它检查str是元音还是包含元音?
remove_vowels或者delete_vowels可能是更好的选择.
变量相同:new是一个字符数组.为什么不给它打电话characters(或者chars如果空间有问题)?
底线:阅读精细手册并了解您的工具.大多数情况下,IRB会话就是调试代码所需的全部内容.
> string= "This Is my sAmple tExt to removE vowels"
#=> "This Is my sAmple tExt to removE vowels"
> string.delete 'aeiouAEIOU'
#=> "Ths s my smpl txt t rmv vwls"
Run Code Online (Sandbox Code Playgroud)
您可以创建这样的方法:
def remove_vowel(str)
result = str.delete 'aeiouAEIOU'
return result
end
remove_vowel("Hello World, This is my sample text")
# output : "Hll Wrld, Ths s my smpl txt"
Run Code Online (Sandbox Code Playgroud)