如何在Ruby中删除数组中的引号

时间:2014-11-14 09:34:23

标签: ruby rspec

我正在使用rspec示例测试来测试第一个Ruby ...

我需要通过这个测试。

it "tokenizes a string" do
    calculator.tokens("1 2 3 * + 4 5 - /").should ==
      [1, 2, 3, :*, :+, 4, 5, :-, :/]
  end

这是我的代码

def tokens(str)
    data = str.split(' ')
    outcomes = []
    data.collect do |x|
      if x.to_i != 0
        outcomes.push(x.to_i)
      elsif x.to_i == 0
        temp = x.gsub('"', '')
        outcomes.push(":#{temp}")
      end
    end
    outcomes
  end

然而,我得到了这些反馈。不知道如何摆脱引号。

Failure/Error: [1, 2, 3, :*, :+, 4, 5, :-, :/]                                                                                                                               
       expected: [1, 2, 3, :*, :+, 4, 5, :-, :/]                                                                                                                                  
            got: [1, 2, 3, ":*", ":+", 4, 5, ":-", ":/"] (using ==)   

4 个答案:

答案 0 :(得分:3)

问题不在于引号。引号表示该元素为String类型,您的规范要求Symbol

outcomes.push(":#{temp}")

应该是

outcomes.push(temp.to_sym)

给你一个想法

2.1.2 :006 > :*.class
 => Symbol 
2.1.2 :007 > ":*".class
 => String 

答案 1 :(得分:3)

试试这个:

outcomes.push(:"#{temp}")

":#{temp}"是字符串,但这个:"#{temp}"符号带有字符串插值。

=>:"+".class
#> Symbol
=> ":+".class
#> String

答案 2 :(得分:2)

Simone Carletti已提供solution for your problem(使用to_sym),但您可以进一步改进代码:

  • split(' ')可以(在这种情况下)替换为split(不带参数)
  • 而不是elsif x.to_i == 0您可以使用else
  • collect(或map)已创建并返回数组,您只需提供值

应用于您的代码:

def tokens(str)
  str.split.map do |x|
    if x.to_i != 0
      x.to_i
    else
      x.to_sym
    end
  end
end

您甚至可以使用ternary if

将其写在一行中
def tokens(str)
  str.split.map { |x| x.to_i != 0 ? x.to_i : x.to_sym }
end

您可能需要修改条件,因为x.to_i != 0会为false返回x = "0"

答案 3 :(得分:1)

":#{temp}"生成以冒号开头的String。

但是您希望将temp字符串翻译为符号,例如temp.to_sym。或者你想构建一个这样的符号::"#{temp}"(注意冒号位于字符串的前面)。