2014-02-06 88 views
27

編輯修正了以下toro2k的評論。`Range#include?`和`Range#cover?`有什麼區別?

Range#include?Range#cover?似乎與源代碼1,2中看到的不同,並且它們效率不同。

t = Time.now 
500000.times do 
    ("a".."z").include?("g") 
end 
puts Time.now - t # => 0.504382493 

t = Time.now 
500000.times do 
    ("a".."z").cover?("g") 
end 
puts Time.now - t # => 0.454867868 

查看源代碼,Range#include?似乎比Range#cover?更加複雜。爲什麼Range#include?不能簡單地作爲Range#cover?的別名?它們有什麼區別?

+0

我也對此感到困惑。看到我的[在這裏回答](http://stackoverflow.com/questions/21507117/select-arrays-between-date-ranges-with-ruby/21507252#21507252)。 –

回答

34

這兩種方法的目的是做兩個稍微不同的事情。在內部,他們的實施也非常不同。你可以看看在documentation的來源和看到.include?是做了很多比.cover?

.cover?方法是關係到Comparable模塊,並檢查是否一個項目將在排序的端點之間配合名單。即使物品不在Range暗示的集合中,它也會返回true。

.include?方法與Enumerable模塊有關,並且檢查項目是否實際上在Range暗示的完整集合中。有一些與數字finessing - 整數範圍計算爲包括所有暗示Float值(我不知道爲什麼)。

這些例子可能會有幫助:

('a'..'z').cover?('yellow') 
# => true 

('a'..'z').include?('yellow') 
# => false 

('yellaa'..'yellzz').include?('yellow') 
=> true 

此外,如果您嘗試

('aaaaaa'..'zzzzzz').include?('yellow') 

你應該注意到它花費的時間比

('aaaaaa'..'zzzzzz').cover?('yellow') 
+3

我明白了。所以現在看來​​'Range#include?'很神祕。 – sawa

6

主要差異更長的時間是include正在檢查w hether對象是range元素之一,並且cover是否返回對象是否位於邊元素之間。你可以看到:

('a'..'z').include?('cc')  #=> false 
('a'..'z').cover?('cc')  #=> true 
0
date_range = {:start_date => (DateTime.now + 1.days).to_date, :end_date => (DateTime.now + 10.days).to_date}     
date_range_to_check_for_coverage = {:start_date => (DateTime.now + 5.days).to_date, :end_date => (DateTime.now + 7.days).to_date}     

(date_range[:start_date]..date_range[:end_date]).include?((DateTime.now + 5.days).to_date)     
#true   
(date_range[:start_date]..date_range[:end_date]).cover?((DateTime.now + 5.days).to_date)     
#true   
(date_range[:start_date]..date_range[:end_date]).include?(date_range_to_check_for_coverage[:start_date]..date_range_to_check_for_coverage[:end_date])     
#true   
(date_range[:start_date]..date_range[:end_date]).cover?(date_range_to_check_for_coverage[:start_date]..date_range_to_check_for_coverage[:end_date])     
#false   

如果不是最後一行返回true?

我問的原因是rubocop在使用include的時候標記衝突?代替封面?顯然,我的邏輯(檢查範圍是否包含在另一個範圍內)不適用於封面?

相關問題