ruby 将具有k,v的嵌套散列转换为具有名称的嵌套散列:k.儿童:[诉...]

643ylb08  于 2023-03-17  发布在  Ruby
关注(0)|答案(1)|浏览(76)

我有一个嵌套的ruby散列,它的深度是任意的,它的键的值是其他键的散列,每个键的值都是其他键的散列,它最终到达最后,最后一个键的值是一个散列数组。

h = {
 foo: { 
        foo_1: { 
                 foo_1_1: [ 
                            x1: {a:1, b:2, c:2},
                            x2: {a:5, b:2, c:2}
                          ],
                 foo_2_1: [ 
                            x1: {a:1, b:2, c:2},
                            x2: {a:5, b:2, c:2}
                          ],
        foo_2: { 
                 foo_2_1: [ 
                            x1: {a:1, b:2, c:2},
                            x2: {a:5, b:2, c:2}
                          ],
                 foo_3_1: [ 
                            x1: {a:1, b:2, c:2},
                            x2: {a:5, b:2, c:2}
                          ],
        foo_3: { 
                 foo_2_1: [ 
                            x1: {a:1, b:2, c:2},
                            x2: {a:5, b:2, c:2}
                          [,
                 foo_3_1: [ 
                            x1: {a:1, b:2, c:2},
                            x2: {a:5, b:2, c:2}
                          ],
      },
 bar: { 
        bar_1: { bar_1_1: [ 
                            x1: {a:1, b:2, c:2},
                            x2: {a:5, b:2, c:2}
                          ],
        bar_2: { bar_2_1: [ 
                            x1: {a:1, b:2, c:2},
                            x2: {a:5, b:2, c:2}
                          ],
        bar_3: { bar_3_1: [ 
                            x1: {a:1, b:2, c:2},
                            x2: {a:5, b:2, c:2}
                          ],
      },
...
}

我需要的是表示为

h = {
 name: foo,
 children: [
       { 
        name: foo_1,
        children: [
               { 
                 name: foo_1_1,
                 children: [ 
                            {x1: {a:1, b:2, c:2}},
                            {x2: {a:5, b:2, c:2}}
                          ]
               },
               {
                 name: foo_2_1, 
                 children: [ 
                            {x1: {a:1, b:2, c:2}},
                            {x2: {a:5, b:2, c:2}}
                          ]
               }
            ]
        },
        {
         name: foo_2,
         children: [
                { 
                 name: foo_2_1, 
                 children: [ 
                            {x1: {a:1, b:2, c:2}},
                            {x2: {a:5, b:2, c:2}}
                          ],
               },
               {
                 name: foo_3_1, 
                 children: [ 
                            {x1: {a:1, b:2, c:2}},
                            {x2: {a:5, b:2, c:2}}
                          ],
               }
            ]
        },
        {
         name: foo_3, 
         children: [
               { 
                 name: foo_2_1: 
                 children: [ 
                            {x1: {a:1, b:2, c:2}},
                            {x2: {a:5, b:2, c:2}}
                          ],
               },
               {
                 name: foo_3_1: 
                 children: [ 
                            {x1: {a:1, b:2, c:2}},
                            {x2: {a:5, b:2, c:2}}
                          ],
               }
            ]
         }
      ]
  }
...

直觉告诉我我错过了一些很简单的事情。
我使用类似下面的代码构建了数据结构:

@tree = Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}
@valid_values = [:foo,:bar,:baz]
@combinations = @valid_values.permutation(@valid_values.length)

data_set.each do |data_hash|

  @combinations.each do |comb|
    @tree.dig(*comb.map{|k|data[k]})&.[]=(data[:x],{a:data[:a],b:data[:b]})
  end

end

我需要能够将生成的@tree散列转换为其他格式,或者找到一种方法来构建第二个结构,就像我从一开始就需要它一样(* 实际上是首选
编辑:
为清晰起见,修改了数据示例 *
此外,“叶”节点的结构并不重要,可以包含任意数据/结构。关键是父键具有name:属性,子数据具有children:属性。最后的数据元素可以是任意复杂的数据元素,但它们没有“子”,因此它们不是原始层次结构的一部分,如果这是有意义的话。

kcugc4gi

kcugc4gi1#

忽略当前输入无效(缺少右大括号)的事实,当前输出也是如此(例如,foofoo_1等不是定义的变量)。
所需的输出将不起作用。需要将输出对象转换为Array,否则name: :foo将被name: :bar覆盖,因为Hash键必须唯一。
如果我理解正确的话,我们可以根据需要使用以下命令生成此Array

def nest(h) 
  h.map do |k,v|
    values = v.is_a?(Hash) ? nest(v) : v 
    {name: k, children: values}
  end 
end

输入如下:

h = {:foo=>
  {:foo_1=>
    {:foo_1_1=>[{:x1=>{:a=>1, :b=>2, :c=>2}, :x2=>{:a=>5, :b=>2, :c=>2}}],
     :foo_2_1=>[{:x1=>{:a=>1, :b=>2, :c=>2}, :x2=>{:a=>5, :b=>2, :c=>2}}]},
   :foo_2=>
    {:foo_2_1=>[{:x1=>{:a=>1, :b=>2, :c=>2}, :x2=>{:a=>5, :b=>2, :c=>2}}],
     :foo_3_1=>[{:x1=>{:a=>1, :b=>2, :c=>2}, :x2=>{:a=>5, :b=>2, :c=>2}}]},
   :foo_3=>
    {:foo_2_1=>[{:x1=>{:a=>1, :b=>2, :c=>2}, :x2=>{:a=>5, :b=>2, :c=>2}}],
     :foo_3_1=>[{:x1=>{:a=>1, :b=>2, :c=>2}, :x2=>{:a=>5, :b=>2, :c=>2}}]}},
 :bar=>
  {:bar_1=>
    {:bar_1_1=>[{:x1=>{:a=>1, :b=>2, :c=>2}, :x2=>{:a=>5, :b=>2, :c=>2}}]},
   :bar_2=>
    {:bar_2_1=>[{:x1=>{:a=>1, :b=>2, :c=>2}, :x2=>{:a=>5, :b=>2, :c=>2}}]},
   :bar_3=>
    {:bar_3_1=>[{:x1=>{:a=>1, :b=>2, :c=>2}, :x2=>{:a=>5, :b=>2, :c=>2}}]}}}

您将收到以下输出:

nest(h) 
#=> [{:name=>:foo,
#  :children=>
#   [{:name=>:foo_1,
#     :children=>
#      [{:name=>:foo_1_1,
#        :children=>[{:x1=>{:a=>1, :b=>2, :c=>2}, :x2=>{:a=>5, :b=>2, :c=>2}}]},
#       {:name=>:foo_2_1,
#        :children=>
#         [{:x1=>{:a=>1, :b=>2, :c=>2}, :x2=>{:a=>5, :b=>2, :c=>2}}]}]},
#    {:name=>:foo_2,
#     :children=>
#      [{:name=>:foo_2_1,
#        :children=>[{:x1=>{:a=>1, :b=>2, :c=>2}, :x2=>{:a=>5, :b=>2, :c=>2}}]},
#       {:name=>:foo_3_1,
#        :children=>
#         [{:x1=>{:a=>1, :b=>2, :c=>2}, :x2=>{:a=>5, :b=>2, :c=>2}}]}]},
#    {:name=>:foo_3,
#     :children=>
#      [{:name=>:foo_2_1,
#        :children=>[{:x1=>{:a=>1, :b=>2, :c=>2}, :x2=>{:a=>5, :b=>2, :c=>2}}]},
#      {:name=>:foo_3_1,
#        :children=>
#         [{:x1=>{:a=>1, :b=>2, :c=>2}, :x2=>{:a=>5, :b=>2, :c=>2}}]}]}]},
# {:name=>:bar,
#  :children=>
#   [{:name=>:bar_1,
#     :children=>
#      [{:name=>:bar_1_1,
#        :children=>
#         [{:x1=>{:a=>1, :b=>2, :c=>2}, :x2=>{:a=>5, :b=>2, :c=>2}}]}]},
#    {:name=>:bar_2,
#     :children=>
#      [{:name=>:bar_2_1,
#        :children=>
#         [{:x1=>{:a=>1, :b=>2, :c=>2}, :x2=>{:a=>5, :b=>2, :c=>2}}]}]},
#    {:name=>:bar_3,
#     :children=>
#      [{:name=>:bar_3_1,
#        :children=>
#         [{:x1=>{:a=>1, :b=>2, :c=>2}, :x2=>{:a=>5, :b=>2, :c=>2}}]}]}]}]

相关问题