【问题标题】:What is the difference between `Range#include?` and `Range#cover?`?`Range#include?` 和 `Range#cover?` 有什么区别?
【发布时间】:2014-02-06 16:47:15
【问题描述】:

编辑修正了以下 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? 的别名,它们有什么区别?

【问题讨论】:

标签: ruby range


【解决方案1】:

这两种方法旨在故意做两件略有不同的事情。在内部,它们的实现方式也非常不同。您可以查看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')

【讨论】:

  • 我明白了。所以现在我觉得Range#include? 非常神秘。
  • 你不是在开玩笑,('aaaaaa'..'zzzzzz').include?('yellow') 需要几分钟才能运行!
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:
    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 标记冲突?代替封面?很明显,我的逻辑(检查范围是否包含在另一个范围中)不适用于覆盖?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-18
      • 2010-10-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多