我有一个名为“Marks”的列,其中包含类似的值 标记= [100,200,150,157,....]
我需要使用以下键为这些标记指定等级
<25=0, <75=1, <125=2, <250=3, <500=4, >500=5
If Marks < 25, then Grade = 0, if marks < 75 then grade = 1.
我可以对结果进行排序,并使用Ruby的find函数找到匹配的第一条记录。这是最好的方法吗?或者有没有办法通过向表中添加下限和上限列并使用键填充这些范围来使用键来准备范围?标记也可以有小数例Ex:99.99
答案 0 :(得分:0)
不使用Rails,你可以这样做:
marks = [100, 200, 150, 157, 692, 12]
marks_to_grade = { 25=>0, 75=>1, 125=>2, 250=>3, 500=>4, Float::INFINITY=>5 }
Hash[marks.map { |m| [m, marks_to_grade.find { |k,_| m <= k }.last] }]
#=> {100=>2, 200=>3, 150=>3, 157=>3, 692=>5, 12=>0}
使用Ruby 2.1,你可以这样写:
marks.map { |m| [m, marks_to_grade.find { |k,_| m <= k }.last] }.to_h
以下是发生的事情:
Enumerable#map(a.k.a collect
)将每个标记m
转换为数组[m, g]
,其中g
是为该标记计算的等级。例如,当map
将marks
的第一个元素传递到其块中时,我们有:
m = 100
a = marks_to_grade.find { |k,_| m <= k }
#=> marks_to_grade.find { |k,_| 100 <= k }
#=> [125, 2]
a.last
#=> 2
因此标记100
已映射到[100, 2]
。 (我已使用占位符_
替换了键变量对的值的块变量,以引起注意这个值未在块内的计算中使用的事实。也可以使用,比方说,_v
作为占位符。)其余的标记也是类似的映射,导致:
b = marks.map { |m| [m, marks_to_grade.find { |k,_| m <= k }.last] }
#=> [[100, 2], [200, 3], [150, 3], [157, 3], [692, 5], [12, 0]]
最后
Hash[b]
#=> {100=>2, 200=>3, 150=>3, 157=>3, 692=>5, 12=>0}
或者,对于Ruby 2.1 +
b.to_h
#=> {100=>2, 200=>3, 150=>3, 157=>3, 692=>5, 12=>0}
答案 1 :(得分:0)
您可以使用update_all
:
Student.where(:mark => 0...25).update_all(grade: 0)
Student.where(:mark => 25...75).update_all(grade: 1)
Student.where(:mark => 75...125).update_all(grade: 2)
Student.where(:mark => 125...250).update_all(grade: 3)
Student.where(:mark => 250...500).update_all(grade: 4)
Student.where("mark > ?", 500).update_all(grade: 5)