3

Hash オブジェクトは次のようになります。配列とハッシュ値の両方がありますが、入れ子は常に「子」配列の値で発生します。

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

次の (非再帰的な) インスタンス メソッド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
于 2013-08-29T05:34:26.300 に答える
-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 に答える