转换多组结果集的哈希结果

时间:2014-06-08 13:42:34

标签: ruby-on-rails ruby arrays hash

这是Product.group([:name, :category]).order([:name, :category]).count

的输出
{
  ["Product A", "Category 2"]=>42,
  ["Product A", "Category 3"]=>83,
  ["Product A", "Category 4"]=>47,
  ["Product B", "Category 2"]=>1,
  ["Product B", "Category 3"]=>4,
  ["Product B", "Category 4"]=>10,
  ["Product C", "Category 3"]=>2,
  ["Product C", "Category 4"]=>4,
  ["Product D", "Category 1"]=>6,
  ["Product D", "Category 2"]=>13,
  ["Product D", "Category 3"]=>57,
  ["Product D", "Category 4"]=>27
}

每种产品可以是1-4类。我需要计算0和最终转换的数量。

所需的转换数组列:产品名称,类别1的计数,类别2的计数,类别3的计数和类别4的计数:

[
  ["Product A",  0, 42, 83, 47],
  ["Product B",  0,  1,  4, 10],
  ["Product C",  0,  0,  2,  4],
  ["Product D",  6, 13, 57, 27]
]

1 个答案:

答案 0 :(得分:2)

groups.group_by { |(p,_),_| p }.map do |product, prod_groups| 
  [product, *(1..4).map do |category| 
    (prod_groups.find {|(_, c), v| c == "Category #{category}" }||[0]).last
  end]
end
# => [["Product A", 0, 42, 83, 47], ["Product B", 0, 1, 4, 10], ["Product C", 0, 0, 2, 4], ["Product D", 6, 13, 57, 27]] 

任意类别名称的另一个选项:

CATEGORY_NAMES = ["Category 1", "Category 2", "Category 3", "Category 4"]

groups.group_by { |(p,_),_| p }.map do |product, prod_groups| 
  sub_groups = Hash[prod_groups.map { |(p, c), v| [c, v] }]
  sub_groups.default = 0
  [product, *CATEGORY_NAMES.map { |c| sub_groups[c] }]
end
# => [["Product A", 0, 42, 83, 47], ["Product B", 0, 1, 4, 10], ["Product C", 0, 0, 2, 4], ["Product D", 6, 13, 57, 27]]