3

Hash 对象如下所示,它同时具有数组和哈希值,但嵌套总是发生在“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

4 回答 4

1

The following (non-recursive) instance method Hash#depth returns the desired measure of depth. I've add a puts statement to display the intermediate calculations.

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
于 2013-08-29T05:34:26.300 回答
-1

如果您特别想找到“孩子”键的深度,您可以使用这种方法:

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
于 2013-08-29T04:43:56.670 回答
-1

这将找到任何嵌套哈希的深度,还遍历数组并为其分配零深度。

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
于 2013-08-29T00:03:41.633 回答
-1

这应该适用于您的情况:

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)
于 2013-08-29T01:14:19.050 回答