我需要获得哈希表中最常用的药物名称。
数组数据为:
Medicine.create([{name: "Apixibucil", patient_id: 1, review_id: 17, nurse_id: 2},
{name: "Adriacilin", patient_id: 1, review_id: 17, nurse_id: 12},
{name: "Tiaferol", patient_id: 4, review_id: 2, nurse_id: 17},
{name: "Afalinum", patient_id: 6, review_id: 7, nurse_id: 10},
{name: "Afalinum", patient_id: 9, review_id: 9, nurse_id: 9},
{name: "Afalinum", patient_id: 22, review_id: 13, nurse_id: 1}])
我写的代码是(该方法是CLI的一部分,这就是为什么要包含它的原因):
def most_common_medicine_on_study
puts "Do you want to know the most popular medicine in the study?"
puts ">"
input = gets.chomp
if input == "yes" || "y"
Medicine["data"].each do |meds|
meds["name"].max_by {|name| name.length}
end
end
end
答案 0 :(得分:3)
使用有效的Ruby数组:
medicine = [{name: "Apixibucil", patient_id: 1, review_id: 17, nurse_id: 2},
{name: "Adriacilin", patient_id: 1, review_id: 17, nurse_id: 12},
{name: "Tiaferol", patient_id: 4, review_id: 2, nurse_id: 17},
{name: "Afalinum", patient_id: 6, review_id: 7, nurse_id: 10},
{name: "Afalinum", patient_id: 9, review_id: 9, nurse_id: 9},
{name: "Afalinum", patient_id: 22, review_id: 13, nurse_id: 1}]
您可以使用Enumerable#group_by
和Hash#transform_values
:
medicine.group_by{ |h| h[:name] }.transform_values { |v| v.size}.max_by { |_, v| v }
或者使用Enumerable#each_with_object
使用Hash#new
的默认值为0,以进行计数:
medicine.each_with_object(Hash.new(0)) { |h, o| o[h[:name]] += 1 }.max_by { |_, v| v }
两种方法都使用Enumerable#max_by
来获取最大计数,并返回:
["Afalinum", 3]
Medicine.group(:name).count
# => { 'Apixibucil' => 1, 'Adriacilin' => 1, 'Tiaferol' => 1, 'Afalinum' => 3 }
答案 1 :(得分:0)
这是一个解决方案。
Medicine['data'].reduce Hash.new(0) do |count, med|
count[med[:name]] += 1
count
end.max_by(&:last)
#=> ["Afalinum", 3]
1)减少所有值均默认为0的哈希。
2)计算每个医学名称的出现。
3)从计数器返回最大计数。
为了让每个人都了解建议的方法在哪里运行的性能,这里是速度和内存使用情况的输出。为了运行测试,我复制了数据以使其具有约3,000,000个条目。
benchmarker do
result = data.reduce Hash.new(0) do |count, med|
count[med[:name]] += 1
count
end.max_by(&:last)
puts result
end
#=> [Afalinum, 1500000]
#=> {"ruby":"2.5.1","elapsed_time":0.72,"garbage_collection":"on","memory_used":"0 MB","garbage_collection_count":1}
benchmarker do
result = data.each_with_object(Hash.new(0)) { |h, o| o[h[:name]] += 1 }.max_by { |_, v| v }
puts result
end
#=> [Afalinum, 1500000]
#=> {"ruby":"2.5.1","elapsed_time":0.72,"garbage_collection":"on","memory_used":"0 MB","garbage_collection_count":1}
benchmarker do
result = data.group_by { |h| h[:name] }.transform_values { |v| v.size}.max_by { |_, v| v }
puts result
end
#=> [Afalinum, 1500000]
#=> {"ruby":"2.5.1","elapsed_time":0.52,"garbage_collection":"on","memory_used":"18 MB","garbage_collection_count":2}
我发现有趣的是group_by
方法实际上可以更快地处理计算,尽管这样做消耗了相当多的内存。第一个在字面上是一样的,由开发人员自行选择,让他们选择更具可读性的方法。