我在应用程序中使用的是Ruby 2.6。
我想删除哈希数组中的重复元素。这是我的输入
array_of_hashes = [
{"Date"=> "2019-05-6", "ID" => 100, "Rate" => 10, "Count" => 1},
{"Date"=> "2019-05-6", "ID" => 100, "Rate" => nil, "Count" => 0},
{"Date"=> "2019-05-6", "ID" => 101, "Rate" => 25, "Count" => 3},
{"Date"=> "2019-05-6", "ID" => 102, "Rate" => nil, "Count" => 0},
{"Date"=> "2019-05-6", "ID" => 102, "Rate" => 35, "Count" => 0},
{"Date"=> "2019-05-6", "ID" => 103, "Rate" => 20, "Count" => 6}
]
我正在为应用程序的需要从哈希中创建键,值对。
result = array_of_hashes.map { |row| [[row['ID'], row['Date'], row] }.to_h
如果在哈希中有两个记录具有相同的“ ID”和“ Date”值,我想在“ Rate”!= 0的行中排行,其中输入记录的顺序可能会乱序。这是我的实际和预期结果。
实际结果:
{[100, "2019-05-6"]=>{"Date"=>"2019-05-6", "ID"=>100, "Rate"=>nil, "Count"=>0},
[101, "2019-05-6"]=>{"Date"=>"2019-05-6", "ID"=>101, "Rate"=>25, "Count"=>3},
[102, "2019-05-6"]=>{"Date"=>"2019-05-6", "ID"=>102, "Rate"=>35, "Count"=>0},
[103, "2019-05-6"]=>{"Date"=>"2019-05-6", "ID"=>103, "Rate"=>20, "Count"=>6}}
预期结果:
{[100, "2019-05-6"]=>{"Date"=>"2019-05-6", "ID"=>100, "Rate"=>10, "Count"=>1},
[101, "2019-05-6"]=>{"Date"=>"2019-05-6", "ID"=>101, "Rate"=>25, "Count"=>3},
[102, "2019-05-6"]=>{"Date"=>"2019-05-6", "ID"=>102, "Rate"=>35, "Count"=>0},
[103, "2019-05-6"]=>{"Date"=>"2019-05-6", "ID"=>103, "Rate"=>20, "Count"=>6}}
如何获得上述预期结果?
答案 0 :(得分:3)
这里是另一个按选项分组
array_of_hashes.group_by {|h| h.values_at("ID","Date")}.transform_values do |v|
v.find {|r| r["Rate"]}
end
#=> {[100, "2019-05-6"]=>{"Date"=>"2019-05-6", "ID"=>100, "Rate"=>10, "Count"=>1},
# [101, "2019-05-6"]=>{"Date"=>"2019-05-6", "ID"=>101, "Rate"=>25, "Count"=>3},
# [102, "2019-05-6"]=>{"Date"=>"2019-05-6", "ID"=>102, "Rate"=>35, "Count"=>0},
# [103, "2019-05-6"]=>{"Date"=>"2019-05-6", "ID"=>103, "Rate"=>20, "Count"=>6}}
按ID和日期分组,然后将Hash
值转换为第一个Hash
,其中“费率”不是nil
。
如果可以接受多个值,则可以用find_all
或select
代替find
。
如果要保留原始结构,只需在末尾添加values
。
答案 1 :(得分:2)
我们可以通过一次通过array_of_hashes
来构建所需的哈希。
array_of_hashes.each_with_object({}) do |g,h|
k = [g['ID'], g['Date']]
h.update(k=>g) unless h.key?(k) && h[k]['Rate'] != nil
end
#=> {[100, "2019-05-6"]=>{"Date"=>"2019-05-6", "ID"=>100, "Rate"=>10, "Count"=>1},
# [101, "2019-05-6"]=>{"Date"=>"2019-05-6", "ID"=>101, "Rate"=>25, "Count"=>3},
# [102, "2019-05-6"]=>{"Date"=>"2019-05-6", "ID"=>102, "Rate"=>35, "Count"=>0},
# [103, "2019-05-6"]=>{"Date"=>"2019-05-6", "ID"=>103, "Rate"=>20, "Count"=>6}}
这假设如果array_of_hashes
的两个元素在'ID'
和'Date'
的值上匹配,并且nil
的值都不为'Rate'
,保留两个哈希中的第一个。如果应保留两者中的后者,则将方法的第二行更改为:
h.update(k=>g) unless h.key?(k) && g['Rate'].nil?
答案 2 :(得分:1)
使用group_by并从值中过滤零利率。
array_of_hashes
.group_by { |h| [h["ID"], h["Date"]] }
.map { |key, values| [key, values.reject { |row| row["Rate"].nil? }.last] }
.to_h