如何在 ruby 中递归构建嵌套的 json/hash 对?

How to recursively build nested json/hash pairs in ruby?

我有一个 ruby 哈希对象的列表(我在最后将它们变成 json)我需要按照对象在列表中出现的顺序变成嵌套对。所以,如果我有

arry =[  {:name => "joe"},  {:type => "normal"}, {:animal => "dog"},  {:age => 5}, {a: 1}, {b: 2}, {c: 3}, {d: 4}]

我需要将其转化为:

{:first => 
         {:first => {:first => {:name => "joe"},
                     :second => {:type => "normal"}},
         :second => {:first => {:animal => "dog"},
                     :second => {:age => 5}}
         }, 
:second =>
         {:first => {:first => {a: 1},
                     :second => {b: 2}},
         :second => {:first => {c: 3},
                     :second => {d: 4}}} 

这可以根据输入列表的长度进行嵌套。

我完全不知道如何递归执行此操作。它有点像平衡二叉树,其中数据仅位于叶子上。我似乎找不到任何专门这样做的算法。我也读过 B+ 树,但这不是二元和平衡的。

像往常一样,我觉得我缺少一些简单而明显的东西。也许我缺少某种内置的 ruby/json 功能?

你可以这样做(注意我添加了一个元素 {e: 5} 这样散列的数量就不会是二的幂):

arr= [{   name: "joe"    },
      {   type: "normal" },
      { animal: "dog"    },
      {    age: 5        },
      {      a: 1        },
      {      b: 2        },
      {      c: 3        },
      {      d: 4        },
      {      e: 5        }]

def hashify(arr)
  return arr.first if arr.size == 1
  half = (arr.size+1)/2
  { first: hashify(arr[0,half]) }.merge(second: hashify(arr[half..-1]))
end

hashify(arr)
  #=> { :first=>
  #       { :first=>
  #           { :first=>{ :first=>
  #                         { :name=>"joe" }, :second=>{ :type=>"normal" }
  #                     },
  #             :second=> { :animal=>"dog" }
  #           },
  #         :second=>
  #           { :first=>{:age=>5}, :second=>{:a=>1} }
  #      },
  #    :second=>
  #      { :first=>
  #          { :first=>
  #              { :b=>2 }, :second=>{ :c=>3 } },
  #        :second=>
  #          { :first=>{ :d=>4 }, :second=>{ :e=>5 } }
  #      }
  #   }