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

时间:2015-03-17 19:21:16

标签: json ruby hash tree binary-tree

我有一个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功能?

1 个答案:

答案 0 :(得分:2)

你可以这样做(注意我添加了一个元素{e: 5},这样哈希的数量不会是2的幂):

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