1

これは少し複雑ですが、このハッシュをループして、各要素が次の条件のいずれかを満たしているかどうかを確認する必要があります。

値は文字列です

また

値は、ハッシュではなく文字列を含むハッシュです

また

値は、文字列および/またはハッシュを含むハッシュです

また

値は配列です

アップデート:

非常に奇妙なこと... [編集: #collect が配列であるハッシュのキーと値のペアを返すためです]

irb> my_hash['gd:name'].collect(&:class)
=> [Array, Array]

以下のハッシュを見ると、その内部要素のクラスは配列ではなくハッシュである必要がありますか?

検査すると次のようになります。

irb> my_hash['gd:name'].collect(&:inspect)
=> ["[\"gd:givenName\", {\"$t\"=>\"Thomas\"}]", "[\"gd:familyName\", {\"$t\"=>\"Chapin\"}]"]

しかし、それはハッシュのように振る舞います:

irb> my_hash['gd:name']['gd:givenName']
=> {"$t"=>"Thomas"}
irb> my_hash['gd:name']['gd:givenName']['$t']
=> "Thomas"

{
  "gd:etag"=>"\"Rnk7fjVSLyt7I2A9WhVQEU4KRQI.\"",
  "id"=>{
    "$t"=>"da513d38e88d949"
   },
  "gd:name"=>{
    "gd:givenName"=>{"$t"=>"Thomas"}, "gd:familyName"=>{"$t"=>"Chapin"}
  },
  "gd:phoneNumber"=>[
    {
      "rel"=>"mobile",
       "$t"=>"(480) 703-4887"
    }
  ], 
  "gd:email"=>[
    {
      "rel"=>"home",
      "primary"=>"true",
       "address"=>"tchapin@gmail.com"
    }, 
    {
      "rel"=>"work",
      "address"=>"tom@tornadodesign.com"}
  ]
}
4

2 に答える 2

1

ハッシュ値のクラスをテストできます。

hash.each do |key, value|
  if value.is_a? String 
    # do String work
  elsif value.is_a? Hash
    #do Hash work
  elsif value.is_a? Array
    # do Array work
  end
end

編集: Niklas B. からの提案で更新されました。

于 2012-04-06T21:34:40.673 に答える
1

ハッシュ値を調べます。

それぞれの場合に true を返します:

  • 値は文字列または配列です   
  • 値は空ではなく、文字列および/またはハッシュのみを含むハッシュです

何が起こっているかを示すためのいくつかの印刷による解決策:

puts hash.each_pair.all?{|k,v|
  puts "key #{k} = value #{v} class #{v.class}"
  case v
  when String, Array
    true
  when Hash
    return false if v.empty? 
    v.each_pair.all?{|k2,v2|
      puts "inner key #{k2} = value #{v2} class #{v2.class}"
      case v2
      when String, Hash
        true
      else
        false
      end
    }
  else
    false
  end
}

キーを追跡する必要がない場合は、#each_pair を #values に変更できます。

于 2012-04-06T22:10:27.797 に答える