2014-11-14 2 views
3

Я работаю на первый тест Руби тестирования RSpec примеров ...Как удалить кавычки в массиве в Рубине

, который мне нужно пройти этот тест.

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 ==) 
+3

Кстати, ваш код имеет ошибку: вы не можете ввести '0'. –

ответ

3

Попробуйте это:

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

":#{temp}" является строкой, но это :"#{temp}" символ со строкой interpo ляционной.

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

Спасибо, он работает сейчас! Извините, у меня недостаточно репутации, чтобы проголосовать за вас :( – Yumiko

3

Проблема не в кавычках. Цитаты означают, что этот элемент является String, ваш spec ожидает Symbol.

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

должен быть

outcomes.push(temp.to_sym) 

Чтобы дать Вам идею

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

на самом деле просто 'temp.to_sym' – GolfWolf

+0

@ w0lf Хорошая точка, спасибо. –

+0

я пытаюсь изменить это так, но результат все тот же, 'ELSIF x.to_i == 0 температура = x.to_sym outcomes.push ("# {} Темп") конец' – Yumiko

1

":#{temp}" генерирует строку, которая начинается с двоеточия.

Но вы хотите перевести строку temp на символ, как этот temp.to_sym. Или вы хотите создать такой символ: :"#{temp}" (обратите внимание, что двоеточие находится перед строкой).

+0

Спасибо за вашу помощь, =) Вы гений – Yumiko

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".

+0

Как насчет 'if x = ~/^ [+ -]? \ D + $ /' вместо 'if x.to_i == 0', чтобы вырезать ошибку @ JörgWMittag Yumiko, в реальном приложении, вам также нужно беспокоиться о плохих данных. Например, «9cats» .to_i => 9'. –

Смежные вопросы