Ruby on rails 在Ruby中使用循环创建深度嵌套哈希
我想使用四个值创建一个嵌套哈希值Ruby on rails 在Ruby中使用循环创建深度嵌套哈希,ruby-on-rails,ruby,Ruby On Rails,Ruby,我想使用四个值创建一个嵌套哈希值type,name,year,value。即,第一个散列的键将是类型,值将是另一个键为名称的散列,然后该散列的值将是另一个键为年份的散列,值为值 我正在迭代的对象数组如下所示: 元素=[ { 年份:“2018年”, 项目:[ { 名称:'name1', 值:“value1”, 类型:“类型1”, }, { 名称:'name2', 值:“value2”, 类型:“类型2”, }, ] }, { 年份:2019年, 项目:[ { 名称:'name3', 值:“valu
type
,name
,year
,value
。即,第一个散列的键将是类型
,值将是另一个键为名称
的散列,然后该散列的值将是另一个键为年份
的散列,值为值
我正在迭代的对象数组如下所示:
元素=[
{
年份:“2018年”,
项目:[
{
名称:'name1',
值:“value1”,
类型:“类型1”,
},
{
名称:'name2',
值:“value2”,
类型:“类型2”,
},
]
},
{
年份:2019年,
项目:[
{
名称:'name3',
值:“value3”,
类型:“类型2”,
},
{
名称:'name4',
值:“value4”,
类型:“类型1”,
},
]
}
]
我使用两个循环将所有值聚集在一起,如下所示:
元素。每个do |元素|
年=元素。年
element.items.each | item|
name=item.name
value=item.value
type=item.type
#TODO:创建嵌套哈希
结束
结束
预期输出如下所示:
{
“类型1”=>{
“名称1”=>{
“2018”=>“价值1”
},
“名称4”=>{
“2019”=>“价值4”
}
},
“类型2”=>{
“名称2”=>{
“2018”=>“价值2”
},
“名称3”=>{
“2019”=>“价值3”
}
}
}
我尝试了一些方法,但似乎没有达到预期效果。如何执行此操作?假设要保留引用(与所需输出不同),请执行以下操作:
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"}}}
这使用了(aka
merge!
)的形式,它使用了一个块(这里{u124;,o,n | o.merge(n)}
)来确定在合并的两个散列中存在的键的值。有关三个块变量的定义,请参见文档(这里{ucode>,o
和n
)
o
和n
将没有公共密钥,因此该操作不需要一个块。您可以添加您尝试过的解决方案吗?您的JSON格式不正确。@AlekseiMatiushkin实际上是一个对象数组,刚刚纠正了它。很好的一个!我想知道我们什么时候会有哈希#bury
或者想要避开这个丑陋的篱笆{=>{=>{=>{=>{/code>:)@AlekseiMatiushkin:类散列;def bury(*keys,val);keys.size>1?self.dig(*keys[0..-2])[keys[-1]]=val:self[keys.first]=val;end;end
(不过散列最好是自动激活的,否则它不会太有用),
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"}}}