1

次のように、キー=>数値のソートされたハッシュがあるとします。

h = { "sebastian" => 0.04, "joshua" => 0.1, "alli" => 0.2, "oliver" = >0.2,  
    ... 
    "wendi" => 1.9, "esther" => 2.1, "mauricio" => 2.6, "fred" => 3.9 }

このハッシュでは、最小値は0.04で、最大値は3.9です。(他のハッシュでは、これは完全に異なる場合があります。たとえば、3..90、1.5..900など)。

これで、次のような順序付き配列ができました。

a = ["lowest", "lower", "low", "normal", "high", "higher", "highest"]

ハッシュ内の任意の1つの値、たとえば1.9が与えられた場合、この値が配列に記述された範囲のどこにあるかをどのように把握できますか?

(ここでRubyと数学の新しさを許してください!)

ありがとう!

更新1:

不明な質問についてお詫びします。まだこれを説明する方法を理解しようとしています。

これは、私が現在どのように問題を解決しているかの概念的な例です。

scores = { "sebastian" => 0.04, "joshua" => 0.1, "alli" => 0.2, "oliver" => 0.2, 
           "wendi" => 1.9, "esther" => 2.1, "mauricio" => 2.6, "fred" => 3.9 }
adjectives = ["lowest", "lower", "low", "average", "high", "higher", "higher"]

scores.each_pair do |student, score|
    adj_idx = case score
        when 3.35..4 then 6
        when 2.8..3.34 then 5
        when 2.25..2.7 then 4
        when 1.7..2.24 then 3
        when 1.15..1.6 then 2
        when 0.6..1.16 then 1
        else 0
    end
    puts "#{student} score was in the #{adjectives[adj_idx]}."
end

だから私の質問:変化する可能性のある学生のスコアの範囲(たとえば、スコアはGPA 0.0..4.0、またはテストのスコア0..110)と、変化する可能性のある「形容詞」の範囲(たとえば、「より高い」)を考えると「」と「より低い」は削除される可能性があります)、上記のように各ケースを「手動で」作成せずに、スコアを形容詞にマッピングする方法はありますか。

再度、感謝します!

更新2:

ご協力ありがとうございます。私は次の解決策が機能していると思います。重要な式は次のとおりです。

adj_idx =((adjectives.size --1)*((score --min_score).to_f /(max_score --min_score).to_f)).round

min_score = scores.values.min
max_score = scores.values.max

scores.each_pair do |student, score|
    adj_idx = ( (adjectives.size - 1) * ((score - min_score).to_f / (max_score - min_score).to_f)  ).round
    puts "#{student} score was in the #{adjectives[adj_idx]} range."
end
4

3 に答える 3

1

値の範囲を同じサイズのサブ範囲に線形に分割する場合は、次の方法でうまくいくはずです。

min = scores.values.min
max = scores.values.max
nsub = adjectives.size
tresholds = (1..nsub).map do |n|
  min + (max - min) * (n / nsub.to_f)
end

scores.each_pair do |student, score|
  adj_index = tresholds.index {|t| t >= score }
  puts "#{student} score was in the #{adjectives[adj_idx]}."
end
于 2012-11-12T09:08:24.747 に答える
0

次の範囲で配列を定義できます。

a = [["lowest",(0.01..0.09), ["lower",(0.1..0.9)], ...]

次に、ハッシュを反復処理して、リテラル範囲を割り当てます。

h.each do |key,value|
  literal_range = a.find { |(literal,range)| range.include?(value) }.first
  h[key] = literal_range if literal_range
end

結果は次のようになります。

{ "sebastian" => 'lowest', "joshua" => 'lower', ... }

質問はそれほど明確ではないので、私はいくつかの推測をしましたが、それはあなたに何か考えることを与えると思います。

于 2012-11-12T01:17:32.173 に答える
0

あなたは自分自身を定義する必要がlowestありlowerます

rankings = {0.04         => 'lowest',
            (0.05..1.00) => 'lower',
            (1.01..1.50) => 'low',
            (1.51..2.50) => 'normal',
            (2.51..2.90) => 'high',
            (2.91..3.89) => 'higher',
            3.90         => 'highest',
           }

次に、次のことを実行できます。

puts rankings.detect { |range, ranking| range === h['joshua'] }.last
#=> lower
于 2012-11-12T01:28:16.653 に答える