#ruby-on-rails #ruby #arrays #hash
#ruby-on-rails #ruby #массивы #хэш
Вопрос:
Я только начинаю (надеюсь!) изучите программирование / ruby on rails и попытайтесь поместить результаты хэша в массив с помощью:
ApplicationController:
def css_class
css = Array.new
product = {@product.oil => ' oil', @product.pressure_meters => ' pressure_meters', @product.commercial => 'commercial'}
product.each do |key, value|
if key == true
css.push(value)
end
end
сss.join
end
И это в ProductsController:
def create
@product = Product.new(params[:product])
@product.css_class = css_class
respond_to do |format|
if @product.save
format.html { redirect_to @product, notice: 'Product was successfully created.' }
format.json { render json: @product, status: :created, location: @product }
else
format.html { render action: "new" }
format.json { render json: @product.errors, status: :unprocessable_entity }
end
end
end
Кажется, что это сохраняет только последнее, что было помещено в массив, я попробовал приведенный ниже код самостоятельно, и, похоже, он работает, поэтому я озадачен тем, где я ошибаюсь?
def css_class
css = Array.new
product = {1 => ' pressure_meters', 2 => ' oil'}
product.each do |key, value|
if key > 0
css.push(value)
end
end
css.join
end
puts css_class
Заранее спасибо.
Ответ №1:
В Ruby Hash
не может быть дубликатов ключей, поэтому
def css_class
css = Array.new
product = { @product.oil => ' oil',
@product.pressure_meters => ' pressure_meters',
@product.commercial => 'commercial' }
product.each do |key, value|
if key == true
css.push(value)
end
end
сss.join
end
не сработает, потому что
irb(main):0> h = { true => 'foo', true => 'bar', false=>'foo', false => 'bar' }
=> {true=>"bar", false=>"bar"}
ваш второй пример работает только потому, что у вас разные ключи (1,2)
поэтому давайте немного переработаем ваш код
def css_class
css = ""
product = { ' oil' => @product.oil,
' pressure_meters' => @product.pressure_meters,
' commercial' => @product.commercial }
product.each do |key, value|
css << key if value
end
сss.strip
end
это можно упростить еще больше, однако предыдущая версия тоже должна работать нормально
def css_class
[ "oil ", "pressure_meters ", "commercial " ].inject(""){ |sum, val| sum = val if @product.send( val.strip ) }.strip
end
Ответ №2:
Вы можете использовать Hash#values
для получения массива значений вашего хэша.
Итак:
product_values = product.values
И условно, вы могли бы выбрать те, которые вы хотите использовать select
, вот так:
product_values = product.select {|k,v| k == true }.values
Который является подробным для:
product_values = product.select {|k,v| k }.values
Комментарии:
1. Хэш в Ruby не может иметь повторяющихся ключей
2. Верно, я просто скопировал исходное условие. Я думаю, что удаление
== true
из исходного кода также решило бы проблему.3. @alexhartley этот ответ намного лучше, чем ваш общепринятый ответ. для меня он более рубиновый.
Ответ №3:
Спасибо, что указали мне правильное направление. Я продолжал получать внутреннюю ошибку сервера 500 с вашим кодом Bohdan, не уверен почему, но поиграл с ней и в конечном итоге обнаружил, что это работает:
def css_class
css = Array.new
product = { ' oil' => @product.oil,
' pressure_meters' => @product.pressure_meters,
' commercial' => @product.commercial }
product.each do |key, value|
css << key if value
end
css.join
end