如何在ruby中做範圍攔截?2個範圍集之間的交集
像這樣:
[-4, 3] intersection [-2, 5] = [-2, 3]
[10, 20] intersection [5, 10] = [10]
[-10, -5] intersection [-8, -3] = [-8,-5]
[-5, -3] intersection [2, 20] = nil
如何在ruby中做範圍攔截?2個範圍集之間的交集
像這樣:
[-4, 3] intersection [-2, 5] = [-2, 3]
[10, 20] intersection [5, 10] = [10]
[-10, -5] intersection [-8, -3] = [-8,-5]
[-5, -3] intersection [2, 20] = nil
def foo((a, b), (c, d))
min, max = [a, c].max, [b, d].min
case min <=> max
when -1 then [min, max]
when 0 then [min]
when 1 then nil
end
end
foo([-4, 3], [-2, 5]) # => [-2, 3]
foo([10, 20], [5, 10]) # => [10]
foo([-10, -5], [-8, -3]) # => [-8, -5]
foo([-5, -3], [2, 20]) # => nil
f = [-4, 3]
s = [-2, 5]
inter = [[f[0],s[0]].max, [f[1],s[2]].min].uniq
inter = nil if inter[1] && inter[1] < inter[0]
或者,'inter = nil,除非inter.sort == inter'。 – sawa
class Range
def range_overlap(other)
[self.min, other.min].max..[self.max, other.max].min
end
end
(-4..3 ).range_overlap -2..5 #=> -2..3
(10..20).range_overlap 5..10 #=> 10..10
(-10..-5).range_overlap -8..-3 #=> -8..-5
(-5..-3).range_overlap -2..20 #=> -2..-3
(1..4 ).range_overlap 2..3 #=> 2..3
r.first > r.last
,如在r = -2..-3
,表示不存在重疊。如果你喜歡nil
在這種情況下,要返回,使用
r = ([self.min, other.min].max)..([self.max, other.max].min)
r.last >= r.first ? r : nil
我也回到[10,10]
而不是說,10
(當然不是[10]
),因爲我相信這會令你的後面的代碼更易於編寫。 (這是類似於返回[[1,2], [3], [4,5]]
,而不是[[1,2], 3, [4,5]]
的方法。)
我認爲它很可能是最好的總是返回Range
對象。允許後續的將被寫入代碼,例如:
r = range_overlap(other)
case r.first <=> r.last
when 1 # r.first > r.last
<put out the trash>
when 0 # r.first == r.last
<let the cat out>
else # r.first < r.last
<go to a movie>
end
'[-4,3]'是*數組*,A *範圍*看起來像這樣:'(-4..3)' – Stefan
而一個['Set'](http://ruby-doc.org/stdlib-2.3.0/libdoc/set/rdoc/Set.html)是別的。 – Stefan
而表達式是非法的。 – sawa