#ruby-on-rails #arrays #ruby-on-rails-3 #loops #hash
#ruby-on-rails #массивы #ruby-on-rails-3 #циклы #хэш
Вопрос:
Я пытаюсь добавить хэши в массив во время итерации по каждому циклу. Вот код моего контроллера: строка, с которой я борюсь, устанавливает переменную @royaltiesbychannel в каждом цикле:
def royalty(isbn)
sales_hash_by_channel = Sale.find_all_by_isbn_id(@isbn).group_by(amp;:channel_id)
sales_hash_by_channel.each do |ch_id, sale_array|
@royaltiesbychannel = Array.new()
value_total_by_channel = sale_array.sum(amp;:value)
quantity_total_by_channel = sale_array.sum(amp;:quantity)
@isbn.rules.each do |rule|
next unless rule.channel_id == ch_id
case quantity_total_by_channel
when 0..5000
@royaltiesbychannel = @royaltiesbychannel << {ch_id => value_total_by_channel * 0.5}
# (some other case-when statements)
end
end
end
В консоли, когда я устанавливаю ch_id и значение на что-то новое и помещаю новые значения в массив:
@royaltiesbychannel = @royaltiesbychannel << {ch_id => value_total_by_channel * 0.5}
Я получаю хороший массив хэшей:
[{1=>100000.0}, {2=>3000.0}]
Однако, когда я выполняю @royaltiesbychannel.inspect в представлении, я получаю только одну пару ключ-значение:
[{2=>3000.0}]
Для ссылки:
@royaltiesbychannel.class = Array
@royaltiesbychannel.class = 1
@sales_hash_by_channel.class = Hash
@sales_hash_by_channel.size = 2
@isbn.rules.size = 4
Таким образом, похоже, что ввод в массив перезаписывается, а не добавляется. Что я делаю не так? Я полностью пропустил момент о том, как работают циклы и .push? Заранее большое спасибо.
Комментарии:
1. во-первых, вы должны поместить всю эту логику в свои модели 🙂
2. Это верно. Я задавался вопросом о том, чтобы сначала заставить это работать, а затем провести рефакторинг…
3. @royaltiesbychannel = @royaltiesbychannel << {ch_id => value_total_by_channel * 0.5} почему вы приравниваете royaltiesbychannel к самому себе? вы можете обойтись без знака =, и, вероятно, именно здесь вы перезаписываете
4. и, возможно, вы могли бы сначала провести рефакторинг и исправить ошибку в процессе 🙂 преобразование его в более чистый и понятный код может прояснить ситуацию для вас, показав вам, почему он не работал в первую очередь 🙂
5. кроме того, у вас есть аргумент isbn в вашем методе, который вы не используете?
Ответ №1:
Вы инициализируете массив внутри цикла:
@royaltiesbychannel = Array.new()
Он повторно инициализируется каждый раз, поэтому вы получаете только один результат. Переместите его за пределы каждого цикла.
Ответ №2:
Ваша @royaltiesbychannel
инициализация находится внутри первого цикла, поэтому каждый раз, когда она снова запускает этот цикл, она очищает массив. Переместите его за пределы цикла, и вы должны получить желаемый результат.
def royalty(isbn)
@royaltiesbychannel = Array.new()
sales_hash_by_channel = Sale.find_all_by_isbn_id(@isbn).group_by(amp;:channel_id)
sales_hash_by_channel.each do |ch_id, sale_array|
value_total_by_channel = sale_array.sum(amp;:value)
quantity_total_by_channel = sale_array.sum(amp;:quantity)
@isbn.rules.each do |rule|
next unless rule.channel_id == ch_id
case quantity_total_by_channel
when 0..5000
@royaltiesbychannel = @royaltiesbychannel << {ch_id => value_total_by_channel * 0.5}
# (some other case-when statements)
end
end
end
Ответ №3:
Вы устанавливаете @royaltiesbychannel
новый объект массива во время каждой итерации sales_hash_by_channel
, если вместо этого вы инициализируете его один раз вне этого цикла?
Комментарии:
1. эй, @ madlep, не могли бы вы отредактировать этот ответ, я случайно нажал «Проголосовать», и теперь он заблокирован. собираюсь вернуть его, как только вы отредактируете ответ, пожалуйста. Спасибо!