编辑修复了toro2k的评论。
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 :(得分: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会标记冲突吗?代替封面?很明显,我的逻辑(检查范围是否包含在另一个范围内)不适用于封面?