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"}}}