我有一系列哈希,比如
[ {:type=>"Meat", :name=>"one"},
{:type=>"Meat", :name=>"two"},
{:type=>"Fruit", :name=>"four"} ]
我希望将其转换为此
{ "Meat" => ["one", "two"], "Fruit" => ["Four"]}
我试过了group_by
,但后来我得到了这个
{ "Meat" => [{:type=>"Meat", :name=>"one"}, {:type=>"Meat", :name=>"two"}],
"Fruit" => [{:type=>"Fruit", :name=>"four"}] }
然后我无法修改它只留下名称而不是完整哈希。我需要在一行中执行此操作,因为在Rails表单上是grouped_options_for_select
。
答案 0 :(得分:16)
array.group_by{|h| h[:type]}.each{|_, v| v.replace(v.map{|h| h[:name]})}
# => {"Meat"=>["one", "two"], "Fruit"=>["four"]}
遵循steenslag的建议:
array.group_by{|h| h[:type]}.each{|_, v| v.map!{|h| h[:name]}}
# => {"Meat"=>["one", "two"], "Fruit"=>["four"]}
答案 1 :(得分:16)
在初始数组上的单次迭代中:
arry.inject(Hash.new([])) { |h, a| h[a[:type]] += [a[:name]]; h }
答案 2 :(得分:2)
array = [{:type=>"Meat", :name=>"one"}, {:type=>"Meat", :name=>"two"}, {:type=>"Fruit", :name=>"four"}]
array.inject({}) {|memo, value| (memo[value[:type]] ||= []) << value[:name]; memo}
答案 3 :(得分:2)
我会这样做:
hsh =[{:type=>"Meat", :name=>"one"}, {:type=>"Meat", :name=>"two"}, {:type=>"Fruit", :name=>"four"}]
p Hash[hsh.group_by{|h| h[:type] }.map{|k,v| [k,v.map{|h|h[:name]}]}]
# >> {"Meat"=>["one", "two"], "Fruit"=>["four"]}
答案 4 :(得分:1)
使用ActiveSuport&#39; Hash#transform_values
:
array.group_by{ |h| h[:type] }.transform_values{ |hs| hs.map{ |h| h[:name] } }
#=> {"Meat"=>["one", "two"], "Fruit"=>["four"]}
答案 5 :(得分:0)
@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]
并返回Array
(外部[group_key, new_array]
)中的block
,to_h
将Array of Array
转换为Hash
(此[[gk1,arr1],[gk2,arr2]...]
转换为{ gk1 => arr1, gk2 => arr2, ...}
)有一个遗漏的步骤在上面的步骤(2)中没有解释。 new_array
由v.map {|h| h[at]}
制作,该方法将at
的每个原始Hash
(h
)元素的值array
转换为{从Array of Hash
个元素移到Array
个元素)。
希望可以帮助其他人理解示例。