@ArupRakshit answer,稍作修改(为了清楚起见,在最后一个示例中添加了该函数):
def group(list, by, at)
list.group_by { |h| h[by] }.map { |k,v| [ k , v.map {|h| h[at]} ] }.to_h
end
sample =[
{:type=>"Meat", :name=>"one", :size=>"big" },
{:type=>"Meat", :name=>"two", :size=>"small" },
{:type=>"Fruit", :name=>"four", :size=>"small" }
]
group(sample, :type, :name) # => {"Meat"=>["one", "two"], "Fruit"=>["four"]}
group(sample, :size, :name) # => {"big"=>["one"], "small"=>["two", "four"]}
请注意,尽管问题中未提及,但您可能希望按原样保留原件sample。一些答案保留了这一点,而另一些则没有。
在分组 ( list.group_by {...}) 之后,进行转换的部分(不修改原始样本的值)是:
.map { |k,v| [ k , v.map {|h| h[at]} ] }.to_h
一些提示:
- 迭代成对的
Hash组(第一个map),其中
- 对于每次迭代,我们接收
|group_key, array]并返回一个Arrayof [group_key, new_array](outer block),
- 最后
to_h将Array of Arrays 转换为Hash(this[[gk1,arr1],[gk2,arr2]...]转换为 this { gk1 => arr1, gk2 => arr2, ...})
上面的步骤(2)中没有说明一个缺失的步骤。new_arrayis made by v.map {|h| h[at]},它只是转换at每个原始Hash( h) 元素的值array(所以我们从Array of Hashes 移动到 an Arrayof 元素)。
希望能帮助其他人理解这个例子。