取出一个字符串并将元音删除后返回

pgh*_*nch 3 ruby string

我正在尝试编写一个带有字符串的函数,并在删除所有元音后返回它.以下是我的代码.

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)

我需要知道使用这种方法我做错了什么.我究竟做错了什么?

Avi*_*Raj 6

我应该使用正则表达式.

str.gsub(/[aeiou]/i, "")
Run Code Online (Sandbox Code Playgroud)


Ste*_*fan 6

找到错误

通过在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)

或者Array#each_index:

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通常已经提供了一种方法.查看内置替代品的其他答案:

命名的东西

Cary Swoveland指出,vowel不是你方法的最佳名称.仔细选择方法,变量和类的名称.希望有一个简短而简洁的方法名称,但它也应该传达其意图.

vowel(str)显然与元音有关,但目前尚不清楚它是什么.它是否会返回元音或所有元音str?它检查str是元音还是包含元音?

remove_vowels或者delete_vowels可能是更好的选择.

变量相同:new是一个字符数组.为什么不给它打电话characters(或者chars如果空间有问题)?

底线:阅读精细手册并了解您的工具.大多数情况下,IRB会话就是调试代码所需的全部内容.


Gag*_*ami 5

> 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)

现场演示