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

检查哈希值。

如果每个都返回真:

  • 值是字符串或数组   
  • 值是一个非空的散列,仅包含字符串和/或散列

带有一些打印的解决方案以显示正在发生的事情:

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
}

If you don't care to keep track of the keys, you can change #each_pair to #values

于 2012-04-06T22:10:27.797 回答