【问题标题】:Ruby finding data type of keys in hashRuby在哈希中查找键的数据类型
【发布时间】:2014-08-20 14:09:32
【问题描述】:

根据 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

这个例子将把点构建到一个散列中,methoddefault 是键。呈现哈希中内容的 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,并且该类将解析数据。如果不是,那么另一个班级将等等。

【问题讨论】:

    标签: ruby hash


    【解决方案1】:

    使用all? 代替每个:

    config.is_a?(Hash) && config['points'].keys.all? {|key| key.is_a? Integer}
    

    注意:有什么理由要检查 config 是否为哈希?如果它来自 yml 文件,那就是多余的。

    要判断是否有更好的方法来执行此操作,您需要显示要将其传递给的方法以及您计划如何调用它。

    【讨论】:

      【解决方案2】:

      这是一种简单的方法(显然具有广泛的应用)。

      代码

      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。在第二种形式中,您当然只能挽救相关的异常(NoMethodErrorTypeError 等)。

      该块也可以写成{ |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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-01-31
        • 2017-03-31
        • 1970-01-01
        • 2017-03-05
        • 1970-01-01
        • 2011-07-01
        • 2016-04-08
        相关资源
        最近更新 更多