改变符号数组

Mutating an array of symbols

我想根据每个符号的最后一个字母在符号末尾添加 es 来改变符号数组。例如数组:

[:alpha, :beta, :kappa, :phi]

将修改为:

[:alphae, :betae, :kappae, :phis]

我可以使用 if ... else 条件和带有字符串数组的正则表达式来完成,但不能使用符号。我尝试将我的符号转换为字符串,对其进行变异,然后再转换回来,但出现错误

s = [:aplha, :beta, :kappa, :phi]

def pluralSym(sym, out = [])
  sym.each do |s|
    s.to_s
    if s.match(/a$/)
      out = s.sub(/a$/, "ae")
    elsif s.match(/i$/)
      out = s.sub(/i$/, "is")
    else
      out = s
    end
    out.to_sym
  end
end

p pluralSym(s)

block in pluralSym': undefined method `sub' for :aplha:Symbol

您可以创建一个方法来接收符号,if 与 /a$//i$/ 匹配,插入后缀,并在每种情况下将其转换为符号,否则只是 return符号

def plural_sym(sym)
  return "#{sym}ae".to_sym if sym =~ /a$/
  return "#{sym}is".to_sym if sym =~ /i$/

  sym
end

p [:aplha, :beta, :kappa, :phi].map(&method(:plural_sym))
# [:aplhaae, :betaae, :kappaae, :phiis]

(&method(:plural_sym)) 只是一种调用函数的方法,将块中的每个元素作为参数传递。

请注意,您不是在改变数组,而是在return创建一个新数组。

您将 symbol 转换为字符串,但没有分配它并继续使用 symbol。也使用 map 而不是 each。快速修复是:

s = [:aplha, :beta, :kappa, :phi]

def pluralSym(sym, out = [])
  sym.map! do |s|
    str = s.to_s
    if str.match(/a$/)
      out = str.sub(/a$/, "ae")
    elsif s.match(/i$/)
      out = str.sub(/i$/, "is")
    else
      out = str
    end
    out.to_sym
  end
end

符号在 ruby 中是不可变的,因此您需要先将它们转换为字符串

s = s.to_s
H = { 'a'=>'e', 'i'=>'s' }

def plural_sym(arr)
  arr.map! { |sym| (sym.to_s + H.fetch(sym[-1], '')).to_sym }
end

arr = [:aplha, :beta, :phi, :rho]        
plural_sym arr
  #=> [:aplhae, :betae, :phis, :rho]
arr
  #=> [:aplhae, :betae, :phis, :rho]

Hash#fetch

下面是一个变体。

H = Hash.new { |h,k| '' }.merge('a'=>'e', 'i'=>'s')

def plural_sym(arr)
  arr.map! { |sym| (sym.to_s + H[sym[-1]]).to_sym }
end

arr = [:aplha, :beta, :phi, :rho]
plural_sym arr
  #=> [:aplhae, :betae, :phis, :rho]
arr
  #=> [:aplhae, :betae, :phis, :rho]

Hash::new