我想使用四个值type,name,year,value创建一个嵌套的散列。也就是说,第一个散列的关键字将是type,值将是另一个具有关键字name的散列,然后该散列的值将是另一个具有关键字year和值为value的散列。
我迭代的对象数组如下所示:
elements = [
{
year: '2018',
items: [
{
name: 'name1',
value: 'value1',
type: 'type1',
},
{
name: 'name2',
value: 'value2',
type: 'type2',
},
]
},
{
year: '2019',
items: [
{
name: 'name3',
value: 'value3',
type: 'type2',
},
{
name: 'name4',
value: 'value4',
type: 'type1',
},
]
}
]我使用两个循环将所有的值集合在一起:
elements.each do |element|
year = element.year
element.items.each |item|
name = item.name
value = item.value
type = item.type
# TODO: create nested hash
end
end预期输出如下所示:
{
"type1" => {
"name1" => {
"2018" => "value1"
},
"name4" => {
"2019" => "value4"
}
},
"type2" => {
"name2" => {
"2018" => "value2"
},
"name3" => {
"2019" => "value3"
}
}
}我尝试了一些方法,但似乎并不像预期的那样有效。我该怎么做呢?
发布于 2019-05-22 14:43:51
假设您希望保留引用(与所需的输出不同),如下所示:
elements = [
{
year: '2018',
items: [
{name: 'name1', value: 'value1', type: 'type1'},
{name: 'name2', value: 'value2', type: 'type2'}
]
},
{
year: '2019',
items: [
{name: 'name3', value: 'value3', type: 'type2'},
{name: 'name4', value: 'value4', type: 'type1'}
]
}
]只需迭代所有内容并还原为散列即可。关于已知形状的结构是一项微不足道的任务:
elements.each_with_object(
Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) } # for deep bury
) do |h, acc|
h[:items].each do |item|
acc[item[:type]][item[:name]][h[:year]] = item[:value]
end
end
#⇒ {"type1"=>{"name1"=>{"2018"=>"value1"},
# "name4"=>{"2019"=>"value4"}},
# "type2"=>{"name2"=>{"2018"=>"value2"},
# "name3"=>{"2019"=>"value3"}}}发布于 2019-05-22 15:04:12
elements.each_with_object({}) { |g,h| g[:items].each { |f|
h.update(f[:type]=>{ f[:name]=>{ g[:year]=>f[:value] } }) { |_,o,n| o.merge(n) } } }
#=> {"type1"=>{"name1"=>{"2018"=>"value1"}, "name4"=>{"2019"=>"value4"}},
# "type2"=>{"name2"=>{"2018"=>"value2"}, "name3"=>{"2019"=>"value3"}}} 这使用Hash#update (也称为merge!)的形式,它使用一个块(这里是{ |_,o,n| o.merge(n) } )来确定合并的两个散列中存在的键的值。有关三个块变量(此处为_、o和n)的定义,请参阅文档。请注意,在执行o.merge(n)时,o和n将没有公用键,因此该操作不需要块。
https://stackoverflow.com/questions/56250363
复制相似问题