字符串中的Ruby首字母缩写创建者



我正在创建一个函数,该函数接受一个字符串并创建一个缩写词,但遇到了错误。当我输入"Complementary metal-oxide semiconductor"时,当我期望"CMOS"时,我得到"CS"作为回报。为什么会发生这种情况,有什么建议吗?我传递了很多其他字符串,它有效,只是在这种情况下不起作用。

class Acronym
def self.abbreviate(phrase)
letters = phrase.split("")
acronym = []
letters.each do |letter|
previous = letters.index(letter) - 1
if previous == -1
acronym.push(letter)
elsif letters[previous] == " " || letters[previous] == "-"
acronym.push(letter)
end
end
acronym.join("").upcase
end
end

简化为

def acronym(str)
str.split(/ |-/).map(&:first).join.upcase
end

以上内容依赖于Rails的activesupport库。这里有一个只有Ruby的变体:

str.split(/ |-/).map { |s| s[0] }.join.upcase 

代码的问题是index()返回给定字母的第一个出现。因此,有两个问题:

  1. 'metal'中的'm'不是字符串中'm'的第一个出现。它出现在"互补"一词中。因此,每当它在字符串中看到"m"时,前一个总是"o",因此不会触发push()
  2. 只要字符串中的第一个字母重复出现(无论位置如何(,就会触发第一个条件。如果将测试字符串中的首字母"C"更改为"C",则可以看到效果。结果将是CSCC,因为"半导体"中有两个"c">

作为一种替代方案,这里有一个使用regex:的选项

def self.abbreviate(phrase)
phrase.gsub('-', ' ')
.scan(/(Aw|(?<=s)w)/)
.flatten
.join.upcase
end

循序渐进:

  1. 借用@DollarChills的.gsub将"-"变成一个空间
  2. scan()返回所有匹配项的数组。正则表达式匹配字符串中的第一个单词和前面有空格的任何单词
  3. scan的结果实际上是一个数组的数组,所以扁平化将不测试它们
  4. 组合成字符串并大写

您可以尝试使用gsub来忽略连字符。

<%= ('Complementary metal-oxide semiconductor').gsub('-', ' ') %>

退货:互补金属氧化物半导体

您在previous = letters.index(letter) - 1中有一个错误

看看你是否能发现它:

arr = [:a, :b, :c, :a]
previous_indexes = arr.map { |n| arr.index(n) - 1 }
you_are_expecting = [-1, 0, 1, 2]
previous_indexes == you_are_expecting
# => false
arr.index(:a) # => 0
arr.index(:b) # => 1
arr.index(:c) # => 2
arr.index(:a) # => 0

要通过迭代获取索引,请使用with_index:

arr = %i[a b c a]
arr.map.with_index { |x, i| [x, i] }
# => [[:a, 0], [:b, 1], [:c, 2], [:a, 3]]

如果您进行了修复,那么您的代码将按您的意图执行。

不过有一个建议:您通常可以避免处理数组索引的细节。看看@Mori的答案是如何在更高层次上运作的。

相关内容

  • 没有找到相关文章

最新更新