【问题标题】:In Ruby, what is good way to filter all the methods of an object that contain the word "time" in it?在 Ruby 中,有什么好方法可以过滤对象中包含“时间”一词的所有方法?
【发布时间】:2010-05-24 03:30:42
【问题描述】:

我尝试了以下方法,但它部分工作:

>> s.methods.map {|n| n if n =~ /time/}
=> [nil, nil, nil, nil, nil, nil, nil, nil, "skip_time_zone_conversion_for_attri
butes", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, ni
l, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, ni
l, "timestamped_migrations", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, n
il, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, n
il, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, n
il, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, n
il, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "time_zone_aware
_attributes", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, n
il, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "default_timezone", nil, n
il, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, n
il, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, n
il, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, n
il, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "recor
d_timestamps", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil, nil, nil]

>> s.methods.each {|n| p n if n =~ /time/}
"skip_time_zone_conversion_for_attributes"
"timestamped_migrations"
"time_zone_aware_attributes"
"default_timezone"
"record_timestamps"
=> ["extended_by", "before_create", "vote_ids=", "save_without_dirty", "_delete"
, "touch", "daemonize", "after_destroy", "skip_time_zone_conversion_for_attribut
es", "methods", "send", "to_query", "becomes", "after_validation", "store_full_s
ti_class?", "save_with_transactions!", "autosave_associated_records_for_votes",
"require_library_or_gem", "enum_for", "taint", "instance_variable_defined?", "ac
     [...] and the rest of the whole array

>> s.methods.filter {|n| n =~ /time/}
NoMethodError: undefined method `filter' for #<Array:0x4de6b00>
        from (irb):93

【问题讨论】:

    标签: ruby arrays filter


    【解决方案1】:

    grep 是实现此目的的另一种简单方法:

    1.9.0 > require 'date'
     => true 
    1.9.0 > x = Date.new
     => #<Date: -1/2,0,2299161> 
    1.9.0 > x.methods.grep /time/
     => ["ctime", "asctime", "strftime"] 
    

    使用您尝试的方法:

    map 将给定块应用于给定枚举的每个元素,返回一个新的枚举。这不是你想要的(如你所见)。

    methods.each 有点工作,但显然简单地打印出结果并不是非常有用。它根本不像 Ruby,但你可以这样做:

    matching_methods = []
    s.methods.each {|m| matching_methods << m if m =~ /time/}
    

    将每个匹配/time/ 的方法累积到matching_methods 数组中。当然,如果你这样做,那么

    s.methods.select { |m| m =~ /time/ }
    

    比较好。

    最后,filter 在 Ruby 中不存在;这就是select(或find_all)的用途。

    【讨论】:

    • 啊,我明白了,select 和 find_all 是同义词,reject 是反义词。
    • @Jian:没错。当我第一次开始使用 Ruby 时,我也一直想使用 filter,但没过多久,select 就开始流行起来了。我认为记住rejectselect 的反义词会有所帮助。
    【解决方案2】:

    使用Enumerable.select

     s.methods.select{|n| n=~/time/}
    

    或者,使用grep

    s.methods.grep(/time/)
    

    【讨论】:

      【解决方案3】:

      这是您使用compact 的方法:

      s.methods.map{|n| n if n =~ /time/}.compact
      

      【讨论】:

        猜你喜欢
        • 2022-01-07
        • 2017-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-31
        相关资源
        最近更新 更多