Ruby - 哈希数组,尝试按键值选择多个键和组

时间:2012-09-18 18:11:59

标签: ruby

我有一组哈希数组的数据,每个哈希表示一个数据记录:

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_ranksget_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来处理这个项目,我使用它作为一个机会来提高我对哈希数组迭代的理解,用数组填充哈希值等等。任何资源/建议都会非常感激。

1 个答案:

答案 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