`Range #include?`和`Range#cover?`之间有什么区别?

时间:2014-02-06 16:47:16

标签: ruby range

编辑修复了toro2k的评论。

Range#include?Range#cover?似乎有所不同,如源代码12所示,它们的效率不同。

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?的别名?它们的区别是什么?

3 个答案:

答案 0 :(得分:45)

这两种方法旨在故意做两件略有不同的事情。在内部,它们的实现也非常不同。您可以查看documentation中的来源,看看.include?的作用远远超过.cover?

.cover?方法与Comparable模块相关,并检查项目是否适合排序列表中的端点。即使该项目不在Range暗示的集合中,它也会返回true。

.include?方法与Enumerable模块相关,并检查项目是否实际位于Range隐含的完整集合中。对数字有一些影响 - 整数范围被计为包括所有隐含的Float值(我不知道为什么)。

这些示例可能有所帮助:

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

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

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

此外,如果您尝试

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

你应该注意到

更长的时间
('aaaaaa'..'zzzzzz').cover?('yellow')

答案 1 :(得分:8)

主要区别在于include正在检查对象是否是范围元素之一,而cover正在返回对象是否在边元素之间。你可以看到:

('a'..'z').include?('cc')     #=> false
('a'..'z').cover?('cc')       #=> true

答案 2 :(得分: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?

我问的原因是当我使用include时rubocop会标记冲突吗?代替封面?很明显,我的逻辑(检查范围是否包含在另一个范围内)不适用于封面?

相关问题