我有一个非常不同的哈希,具体取决于yaml文件中的内容。这是两种可能的结构。
config = {'points' => {2012 => 5.5, 2013 => 6.3}}
config = {'points' => {'method' => 'calculate_periodicaly', 'default' => 10}}
第一个将始终将日期作为键,第二个将具有方法和默认键。
我想将它传递给一个方法,具体取决于它是如何构建的。我有类似的东西,以确定它是否有多年的钥匙
config.is_a?(Hash) && config['points'].has_key?(2012) && config['points'].has_key?(2013)
=> true
我可以为它构建的其他方式做类似的事情。但对我来说这是丑陋的代码。我想做一些事情,它可以找出每个键的数据类型。因此,如果所有键都是数字,那么它应该是日期哈希,如果所有键都是字符串,那么它应该是字符串哈希。
我试过这样的事情
config.is_a?(Hash) && config['points'].keys.each {|key| key.is_a? Integer}
但这只是返回
=> [
[0] 2012,
[1] 2013
]
有更好的方法吗?或许更Ruby的方式呢?
更新
我们检查它的哈希是有时它也可以被称为文字的原因。这里有点yaml
homeowner_policies:
total: active_homeowne
actual: qualifing_homeowner
points:
method: calculated_points_by_selected_policies
default: 0
target: homeowner_industry_target_agaist_market_share
description: Property / Homeowners
这个例子它将点构建成一个哈希,method
和default
是密钥。在哈希中呈现内容的gem。但如果你只想指定直接金额,你可以指定类似这样的东西
homeowner_policies:
conditional: include_homeowner?
total: active_homeowne
actual: qualifing_homeowner
points: 10
target: homeowner_industry_target_agaist_market_share
description: Property / Homeowners
然后第三种可能性是逐年的,所以就像第一个例子一样,但你可以提供多年,每年可以给出不同的分数。
这将用于决定使用数据的方法。
如果这些点基于年份,则类中的requires_parsing?
方法将返回true,该类将解析数据。如果没有,那么另一个班级会等等。
答案 0 :(得分:1)
分别使用all?
:
config.is_a?(Hash) && config['points'].keys.all? {|key| key.is_a? Integer}
注意:您有没有理由查看配置是否为哈希?如果它来自yml文件,那么这是多余的。
要判断是否有更好的方法,您需要显示您想要传递给它的方法,以及您计划如何调用它。
答案 1 :(得分:1)
这是一种简单的方法(显然有广泛的应用)。
<强>代码强>
def confirm_key_type(h, key, klass)
h[key].keys.all? { |k| klass === k } rescue nil
end
或
def confirm_key_type(h, key, klass)
begin
h[key].keys.all? { |k| klass === k }
rescue
nil
end
end
第一种形式称为“内联救援”。它受到一些人的喜爱hated by others。在第二种形式中,您当然可以拯救相关的例外(NoMethodError
,TypeError
等)。
也可以将该块写为{ |k| k.class == k }
或{ |k| k.is_a? k }
。
<强>实施例强>
config = {'points' => {2012 => 5.5, 2013 => 6.3}}
#=> {"points"=>{2012=>5.5, 2013=>6.3}}
confirm_key_type(config, 'points', Fixnum) #=> true
confirm_key_type(config, 'points', String) #=> false
config = {'points' => {'method' => 'calculate_periodicaly', 'default' => 10}}
#=> {"points"=>{"method"=>"calculate_periodicaly", "default"=>10}}
confirm_key_type(config, 'points', Fixnum) #=> false
confirm_key_type(config, 'points', String) #=> true
confirm_key_type(config, 'cats', Fixnum) #=> nil
confirm_key_type(config, :dogs, String) #=> nil
confirm_key_type([1,2,3], 'points', Fixnum) #=> nil
confirm_key_type('goldfish', 'points', String) #=> nil
confirm_key_type(nil, 'points', String) #=> nil