有没有一种快速检查哈希表中键值是符号还是字符串的方法?
一个只有单层键的平面哈希表可以很容易地被查询,但嵌套数据结构则不行。另外,哈希表的键并不仅限于字符串或符号键。你几乎可以使用任何 Ruby 对象作为哈希表的键,只需注意这些对象必须要 #respond_to? 一些特定方法才能正确地作为键。
如果你的哈希表不是嵌套的数据结构,那么你可以简单地询问该哈希表是否其所有顶级键都是符号对象:
p {foo: 1, bar: 2, baz: 3}.keys.all? Symbol
#=> true
Symbol
替换为String
。require "json"
hash = {foo: {bar: 1, baz: 2 }}
hash = JSON.parse hash.to_json
hash
#=> {"foo"=>{"bar"=>1, "baz"=>2}}
def key_type(h)
case h.each_key.map(&:class).uniq
when [String] then String
when [Symbol] then Symbol
else nil
end
end
key_type('cats'=>9, 'dogs'=>2) #=> String
key_type(:cats=>9, :dogs=>2) #=> Symbol
key_type('cats'=>9, :dogs=>2) #=> nil
key_type(:cats=>9, 'dogs'=>2) #=> nil
key_type(9=>'cats') #=> nil
key_type(9=>'cats', 2=>'dogs') #=> nil
key_type({}) #=> nil
h = { 'cats'=>9, 'dogs'=>2 }
那么
a = h.each_key.map(&:class)
#=> [String, String]
b = a.uniq
#=> [String]
因此,返回的是String
。相比之下,如果
h = { 'cats'=>9, :dogs=>2 }
那么
a = h.each_key.map(&:class)
#=> [String, Symbol]
b = a.uniq
#=> [String, Symbol]
所以返回nil
。
#all?
方法来检查哈希表的所有键是否都是符号类型,代码如下所示:
hash = { foo: 1, bar: 2, baz: 3 }
hash.all? { |key, _value| key.is_a?(Symbol) }
#=> true
{ "foo" => 1, "bar" => 2, "baz" => 3 }
。 - Zoran