Может кто-то объяснить, почему значение переменной в моем цикле не обновляется, пока цикл не будет закрыт? - PullRequest
2 голосов
/ 22 декабря 2011

Это моя функция

def rating(array)
  sum_count = array.values.inject(0) { |sum_count,value| sum_count + value }
  run_count = 0
  array.each do |tag,count|
    run_count += count
    cum_distn = run_count/sum_count
    logger.debug "cum_distn is #{cum_distn.to_f}; run_count is #{run_count.to_f}; sum_count is #{sum_count}"
    if cum_distn < 0.25
      ...
    elsif cum_distn < 0.5
      ...
    else
      ...
    end
  end
end

Для 2 объектов в моем массиве с числом 1 каждый мой регистратор показывает это:

cum_distn is 0.0; run_count is 1.0; sum_count is 2
cum_distn is 1.0; run_count is 2.0; sum_count is 2

Кажется, что значение cum_distnобновляется только после завершения одного цикла, в то время как я намерен обновить его непосредственно перед открытием функции if.У меня есть два вопроса:

(а) Почему это происходит (так как я не вижу никакого логического объяснения)?

(б) Как я могу исправить это, чтобы делать то, что я хочу?

Ответы [ 2 ]

3 голосов
/ 22 декабря 2011

Вы используете целочисленное деление, поэтому результат run_count / sum_count будет усечен.Чтобы исправить, просто конвертируйте один из них в Float, прежде чем вычислять cum_distn.Например:

cum_distn = run_count.to_f / sum_count
2 голосов
/ 22 декабря 2011

1) Это происходит потому, что 3/2 #=> 1 но 3.0/2 # => 1.5.Другими словами, integer/integer #=> integer и float/integer #=> float

2) Просто позвоните to_f один раз, в начале (не в цикле, потому что это действительно не работает):

def rating(hash)
  sum_count = hash.values.inject(:+).to_f
  hash.inject(0) do |run_count, (tag, count)|
    run_count += count
    cum_dist = run_count/sum_count
    logger.debug "cum_distn is #{cum_distn}; run_count is #{run_count}; sum_count is #{sum_count}"
    ...
    run_count # return run_count
  end
end
...