Вставить хэш в массив в цикле rails

#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, не могли бы вы отредактировать этот ответ, я случайно нажал «Проголосовать», и теперь он заблокирован. собираюсь вернуть его, как только вы отредактируете ответ, пожалуйста. Спасибо!