1

假设我有一个 key => number 值的排序哈希,如下所示:

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.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

您需要自己定义什么是lowestlower

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 回答
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 回答