2

これが私の機能です

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

それぞれカウントが1の配列内の2つのオブジェクトの場合、ロガーは次のように表示します。

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の値は、1つのループが完了したときにのみ更新されているようですが、if関数が開く直前に更新する予定です。2つの質問があります:

(a)なぜこれが起こっているのですか(論理的な説明が見当たらないため)?

(b)これを修正して自分のやりたいことを行うにはどうすればよいですか?

4

2 に答える 2

2

1)それは起こります3/2 #=> 13.0/2 # => 1.5。言い換えればinteger/integer #=> integerfloat/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
于 2011-12-22T16:03:08.920 に答える