我有一组哈希数组的数据,每个哈希表示一个数据记录:
data = [
{
:id => "12345",
:bucket_1_rank => "2",
:bucket_1_count => "12",
:bucket_2_rank => "7",
:bucket_2_count => "25"
},
{
:id => "45678",
:bucket_1_rank => "2",
:bucket_1_count => "15",
:bucket_2_rank => "9",
:bucket_2_count => "68"
},
{
:id => "78901",
:bucket_1_rank => "5",
:bucket_1_count => "36"
}
]
排名值始终介于1到10之间。
我要做的是选择排名字段(:bucket_1_rank
和:bucket_2_rank
字段)的每个可能值作为我的最终结果集中的键,并且每个键的值将是其关联的:bucket_count
字段中所有值的数组。因此,对于上面的数据,我想到的最终结果是:
桶1:
{"2" => ["12", "15"], "5" => ["36"]}
桶2:
{"7" => ["25"], "9" => ["68"]}
我可以假设字段名称保持不变,或者通过对字段/键名称进行硬编码,或者仅使用group_by
来填充我需要的字段,但我的问题是我工作根据项目规范,每个月使用不同的数据集,其中排名字段的命名略有不同,我想动态识别计数和排名字段的名称,而不是硬编码字段名称。
我写了两个快速帮助器get_ranks
和get_buckets
,它们使用正则表达式返回一个字段数组,这些字段是rank或count字段,因为这些字段总是有文字字符串“_rank”或“ _count“在他们的名字中:
ranks = get_ranks
counts = get_counts
results = Hash.new{|h,k| h[k] = []}
data.each do |i|
ranks.each do |r|
unless i[r].nil?
counts.each do |c|
results[i[r]] << i[c]
end
end
end
end
p results
这似乎很接近,但感觉很尴尬,而且在我看来,必须有更好的方法来遍历这个数据集。由于我没有使用Ruby来处理这个项目,我使用它作为一个机会来提高我对哈希数组迭代的理解,用数组填充哈希值等等。任何资源/建议都会非常感激。
答案 0 :(得分:1)
您可以将其缩短为:
result = Hash.new{|h,k| h[k] = Hash.new{|h2,k2| h2[k2] = []}}
data.each do |hsh|
hsh.each do |key, value|
result[$1][value] << hsh["#{$1}_count".to_sym] if key =~ /(.*)_rank$/
end
end
puts result
#=> {"bucket_1"=>{"2"=>["12", "15"], "5"=>["36"]}, "bucket_2"=>{"7"=>["25"], "9"=>["68"]}}
虽然这假设:bucket_2_item_count
实际上应该是:bucket_2_count
。