我有一个集合:
programmers = [
{:name => "Martin", :speed => 2.0, :daily_wage => 2000},
{:name => "Jarda", :speed => 1.0, :daily_wage => 1300},
{:name => "Lukas", :speed => 0.5, :daily_wage => 900},
{:name => "Pepa", :speed => 1.7, :daily_wage => 2200},
{:name => "Kamil", :speed => 0.4, :daily_wage => 1800},
{:name => "Honza", :speed => 1.2, :daily_wage => 1500},
{:name => "Filip", :speed => 1.1, :daily_wage => 1000}
]
我想计算他们的质量
quality = (pro[:daily_wage] / pro[:speed])
sorted << [pro[:name], pro[:speed], pro[:daily_wage], quality]
按质量排序
sorted.sort_by { |a| a[3] }
我的技术不起作用,你能否给我一些重新设计这个集合的提示,以便在sorted
上进行进一步的迭代?
答案 0 :(得分:2)
这是我做的方式。首先,将计算放在lambda中:
quality = ->(pro) {pro[:daily_wage] / pro[:speed]}
然后你可以简洁地对集合进行排序:
programmers.sort_by &quality
这样您就不需要创建仅用于排序的中间数据结构。
但是,如果你做想要永久保留质量度量,你可以为每个元素调用lambda,添加一个新的键/值对,然后对其进行排序:
programmers.each{|p| p[:quality] = quality[p]}.sort_by{|p| p[:quality]}
注意使用方括号调用lambda,这只是quality.call(p)
答案 1 :(得分:1)
编辑:我最初建议创建一个新的键/值对并同时进行排序:
programmers.sort_by { |h| h[:quality] = (h[:daily_wage]/h[:speed]).round(0) }
当我这样做时,我没有考虑到这将需要为sort_by
完成的每个成对比较的两个元素计算块中的表达式。感谢@Mark指出这一点。 (请参阅他的回答评论。)因此,我已经开始以更直接的方式进行替换并按顺序排序:
arr = programmers.each {|h| h[:quality] = (h[:daily_wage]/h[:speed]).round(0)}
arr.sort_by {|h| h[:quality]}
#=> [{:name=>"Filip", :speed=>1.1, :daily_wage=>1000, :quality=> 909},
# {:name=>"Martin", :speed=>2.0, :daily_wage=>2000, :quality=>1000},
# {:name=>"Honza", :speed=>1.2, :daily_wage=>1500, :quality=>1250},
# {:name=>"Pepa", :speed=>1.7, :daily_wage=>2200, :quality=>1294},
# {:name=>"Jarda", :speed=>1.0, :daily_wage=>1300, :quality=>1300},
# {:name=>"Lukas", :speed=>0.5, :daily_wage=> 900, :quality=>1800},
# {:name=>"Kamil", :speed=>0.4, :daily_wage=>1800, :quality=>4500}]