在Ruby中返回嵌套哈希的最大深度的任何好方法

时间:2013-08-28 23:42:27

标签: ruby hash

Hash对象如下所示,它有数组和哈希值,但是nest总是发生在“children”数组的值:

a = {"id" => "1", "children" => [{"id"=>"11", "children"=>[{"id"=>"111"}]}, {"id"=>"12", "children"=>[{"id"=>"121", "children"=>[{"id"=>"1211"}]}, {"id"=>"122"}]}]}
a.max_depth = 3

4 个答案:

答案 0 :(得分:1)

以下(非递归)实例方法Hash#depth返回所需的深度度量。我添加了puts语句来显示中间计算。

class Hash
  def depth
    arr = values
    d = 0
    loop do
      arr = arr.flatten.select { |e| e.is_a? Hash }
      break d if arr.empty?
      d += 1
      arr = arr.map(&:values)
      puts "d = #{d}, arr = #{arr}"
    end
  end
end

a.depth
d = 1, arr = [["11", [{"id"=>"111"}]], ["12", [{"id"=>"121", "children"=>
                [{"id"=>"1211"}]}, {"id"=>"122"}]]]
d = 2, arr = [["111"], ["121", [{"id"=>"1211"}]], ["122"]]
d = 3, arr = [["1211"]]
  #=> 3

答案 1 :(得分:0)

这将找到任何嵌套哈希的深度,也遍历数组并为它们指定深度为零。

class Hash
  def max_depth
    1 + values.map do |val| 
      if val.respond_to?(:max_depth) 
        val.max_depth
      elsif val.respond_to?(:max)
        val.max { |elt| elt.max_depth }
      else
        0
      end
    end.max
  end
end

答案 2 :(得分:0)

这适用于您的情况:

def array_traverse(array, depth)
  array.each do |i|
    if i.class == Array
      depth = array_traverse(i, depth)
    elsif i.class == Hash
      depth = hash_traverse(i, depth)
    end
  end
  return depth
end

def hash_traverse(hash, depth)
  hash.keys().each do |i|
    depth += 1 if i == 'children' and hash[i].length > 1
    if hash[i].class == Array
      depth = array_traverse(hash[i], depth)
    elsif hash[i].class == Hash
      depth = hash_traverse(hash[i], depth)
    end
  end
  return depth
end

puts hash_traverse(a, 1)

答案 3 :(得分:0)

如果您专门尝试查找“儿童”键的深度,可以使用此方法:

class Hash
  def max_depth
    max_depth = 1
    depth_func = ->(hsh, cur_depth) do
      max_depth = cur_depth if cur_depth > max_depth
      hsh["children"].to_a.each{|h| depth_func.call(h, cur_depth+1)}
      max_depth
    end
    depth_func.call(self, 0)
  end
end

现在您可以尝试代码:

h = {  "id" => "1", "children" => [{"id"=>"11", "children"=>[{"id"=>"111"}]}, 
       {"id"=>"12", "children"=>[{"id"=>"121", "children"=>[{"id"=>"1211"}]}, 
       {"id"=>"122"}]}]}

h.max_depth # 3