0

我有一组数据,它是一个哈希数组,每个哈希代表一个数据记录:

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”:

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 参与过这个项目,我会以此为契机来提高我对遍历哈希数组、使用数组作为值填充哈希等的理解。任何资源/建议将不胜感激。

4

1 回答 1

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.

于 2012-09-18T19:49:55.517 回答