开发者

In Ruby, what is good way to filter all the methods of an object that contain the word "time" in it?

I tried the following and it was partly working:

>> 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,开发者_JAVA技巧 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


grep is another easy way to accomplish this:

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"] 

With the approaches you tried:

map applies the given block to each element of the given enumerable, returning a new enumerable. That's not what you wanted here (as you saw).

methods.each sort of works, but obviously simply printing out the results isn't terribly useful. It wouldn't be Ruby-like at all, but you could have done:

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

to accumulate each method matching /time/ into the matching_methods array. Of course, if you're doing that, then

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

is preferable.

Lastly, filter doesn't exist in Ruby; that's what select (or find_all) is for.


Use Enumerable.select

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

Or, use grep

s.methods.grep(/time/)


Here's your approach with compact:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜