Ruby groupby散列数组转换为数组散列数组?
我正在尝试用ruby进行数据操作 给定这个散列数组Ruby groupby散列数组转换为数组散列数组?,ruby,arrays,Ruby,Arrays,我正在尝试用ruby进行数据操作 给定这个散列数组 peepz = [ { :name => 'ted', :phone => '555-1234', :color => 'red' }, { :name => 'bill', :phone => '555-2222', :color => 'green' }, { :name => 'ted', :phone => '555-3333', :color =>
peepz = [
{
:name => 'ted',
:phone => '555-1234',
:color => 'red'
},
{
:name => 'bill',
:phone => '555-2222',
:color => 'green'
},
{
:name => 'ted',
:phone => '555-3333',
:color => 'orange'
},
{
:name => 'dan',
:phone => '555-7777',
:color => 'violet'
},
{
:name => 'ted',
:phone => '555-4444',
:color => 'yellow'
},
{
:name => 'dan',
:phone => '555-6666',
:color => 'orange'
}
];
我想要这个输出
peepz2 = [
{
:name => 'ted'
:phone => ['555-1212','555-3333','555-4444']
:color => ['red','orange','yellow']
},
{
:name => 'bill'
:phone => ['555-2222']
:color => ['green']
},
{
:name => 'dan'
:phone => ['555-7777','555-6666']
:color => ['violet','orange']
},
]
这是我到目前为止所拥有的
def groupbyer ( peepz, *fields )
peepz.groupby do |peep|
key = ''
fields.each do |field|
key += peep[field].to_s
end
end.each do |group|
????
end
end
groupbyer(peepz, :name)
这种方法必须推广。它不能硬编码peepz的字段
用ruby完成这个任务的好方法是什么?另一种方法使用aka merge的形式!使用块确定合并的两个哈希中存在的键的值:
peepz
.group_by{|h| h[:name]}.values
.map{|a| a.inject{|h1, h2| h1.merge(h2){|k, v1, v2| k == :name ? v1 : [*v1, v2]}}}
代码
范例
对于问题中给出的peepz:
peep_merge(peepz)
#=> [{:name=>"ted",
# :phone=>["555-1234", "555-3333", "555-4444"],
# :color=>["red", "orange", "yellow"]},
# {:name=>"bill",
# :phone=>["555-2222"],
# :color=>["green"]},
# {:name=>"dan",
# :phone=>["555-7777", "555-6666"],
# :color=>["violet", "orange"]}]
解释
最后,要更正:name键的值:
提供上面示例中显示的结果。另一种方法使用aka merge的形式!使用块确定合并的两个哈希中存在的键的值: 代码 范例 对于问题中给出的peepz:
peep_merge(peepz)
#=> [{:name=>"ted",
# :phone=>["555-1234", "555-3333", "555-4444"],
# :color=>["red", "orange", "yellow"]},
# {:name=>"bill",
# :phone=>["555-2222"],
# :color=>["green"]},
# {:name=>"dan",
# :phone=>["555-7777", "555-6666"],
# :color=>["violet", "orange"]}]
解释
最后,要更正:name键的值:
提供上面示例中显示的结果
a = peepz.each_with_object({}) { |g,h|
h.update(g[:name]=>(g.merge(g) { |*_,v|
[v] })) { |_,oh,nh| oh.merge(nh) { |_,ov,nv| ov+nv } } }
#=> {"ted" =>{:name=>["ted", "ted", "ted"],
# :phone=>["555-1234", "555-3333", "555-4444"],
# :color=>["red", "orange", "yellow"]},
# "bill"=>{:name=>["bill"],
# :phone=>["555-2222"],
# :color=>["green"]},
# "dan" =>{:name=>["dan", "dan"],
# :phone=>["555-7777", "555-6666"],
# :color=>["violet", "orange"]}}
b = a.values
#=> [{:name =>["ted", "ted", "ted"],
# :phone=>["555-1234", "555-3333", "555-4444"],
# :color=>["red", "orange", "yellow"]},
# {:name =>["bill"],
# :phone=>["555-2222"],
# :color=>["green"]},
# {:name =>["dan", "dan"],
# :phone=>["555-7777", "555-6666"],
# :color=>["violet", "orange"]}]
b.each { |h| h[:name] = h[:name].first }