(Ruby) How do you check whether a range contains a subset of another range?

后端 未结 10 1469
轻奢々
轻奢々 2021-02-05 11:06

If I have two ranges that overlap:

x = 1..10
y = 5..15

When I say:

puts x.include? y 

the output is:

相关标签:
10条回答
  • 2021-02-05 11:23

    If a range includes either the beginning or the end of a second range, then they overlap.

    (x === y.first) or (x === y.last)
    

    is the same as this:

    x.include?(y.first) or x.include?(y.last)
    
    0 讨论(0)
  • 2021-02-05 11:24

    This method can be used to test overlap between multiple ranges in an efficient way:

    def range_overlap?(ranges)
      sorted_ranges = ranges.sort
      sorted_ranges.each_cons(2).each do |r1, r2|
        return true if r2.first <= r1.last
      end
      return false
    end
    
    
    def test(r)
      puts r.inspect, range_overlap?(r)
      puts '================'
      r = r.reverse
      puts r.inspect, range_overlap?(r)
      puts '================'
    end
    
    
    test [[1,9], [10, 33]]
    test [[1,10], [5, 8]]
    test [[1,10], [10, 33]]
    
    0 讨论(0)
  • 2021-02-05 11:25

    If you're using Ruby 2.6, you can use Range#cover? with another Range.

    (1..5).cover?(2..3)     #=> true
    (1..5).cover?(0..6)     #=> false
    (1..5).cover?(1...6)    #=> true
    
    0 讨论(0)
  • 2021-02-05 11:27

    You could also convert the ranges to sets, since you're basically doing set intersection here. Might be easier if you are dealing with more than two ranges.

    x = (1..10).to_set
    y = (5..15).to_set
    !(x & y).empty? #returns true (true == overlap, false == no overlap)
    
    0 讨论(0)
  • 2021-02-05 11:28

    The efficient way is to compare the limits

    (x.first <= y.last) and (y.first <= x.last)
    
    0 讨论(0)
  • 2021-02-05 11:33

    If you're checking for overlap, then I'd just do

    (x.include? y.first) or (x.include? y.last)
    

    as one range will have to include at least one of the ends of the other. This is more intuitive to me than the accepted conjuction answer, though not quite as efficient as MarkusQ's limit comparison.

    0 讨论(0)
提交回复
热议问题