16

重複する 2 つの範囲がある場合:

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

私が言ったら:

puts x.include? y 

出力は次のとおりです。

false 

2 つの範囲が部分的にしか重複しないためです。

しかし、2 つの範囲の間に部分的な重複がある場合に「true」にしたい場合は、どのように記述すればよいでしょうか? つまり、ある範囲に別の範囲のサブセットが含まれていることを知る方法が必要です。これを Ruby で書くための洗練された方法があると思いますが、私が考えることができる唯一の解決策は冗長です。

4

10 に答える 10

64

効率的な方法は、制限を比較することです

(x.first <= y.last) and (y.first <= x.last)
于 2009-03-30T23:30:41.970 に答える
8

これを広い範囲で使用する場合は注意が必要ですが、これはエレガントな方法です。

(x.to_a & y.to_a).empty?
于 2009-11-12T02:17:03.877 に答える
2

この方法は、効率的な方法で複数の範囲間のオーバーラップをテストするために使用できます。

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]]
于 2012-05-21T11:55:49.900 に答える
2

ここでは基本的に set 交差を行っているため、範囲をsetsに変換することもできます。2 つ以上の範囲を扱っている場合は、より簡単になる可能性があります。

x = (1..10).to_set
y = (5..15).to_set
!(x & y).empty? #returns true (true == overlap, false == no overlap)
于 2011-05-29T17:15:48.587 に答える
1

オーバーラップをチェックしているなら、私はただやります

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

一方の範囲には、もう一方の端の少なくとも 1 つを含める必要があるためです。これは、MarkusQ の制限比較ほど効率的ではありませんが、受け入れられている結合回答よりも直感的です。

于 2009-08-26T20:44:52.883 に答える
1

範囲に 2 番目の範囲の先頭または末尾が含まれる場合、それらは重複します。

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

これと同じです:

x.include?(y.first) or x.include?(y.last)
于 2009-03-31T01:07:28.617 に答える
1

しかし、2 つの範囲の間に部分的な重複がある場合に「true」にしたい場合は、どのように記述すればよいでしょうか?

範囲を配列に変換し、&演算子 (連結)を使用できます。これにより、両方の配列にあるすべての要素を含む新しい配列が返されます。結果の配列が空でない場合は、重複する要素がいくつかあることを意味します。

def overlap?(range_1, range_2)
  !(range_1.to_a & range_2.to_a).empty?
end
于 2009-03-31T16:07:37.330 に答える
-1

いくつかの有用な列挙可能なメソッド:

# x is a 'subset' of y
x.all?{|n| y.include? n}
# x and y overlap
x.any?{|n| y.include? n}
# x and y do not overlap
x.none?{|n| y.include? n}
# x and y overlap one time
x.one?{|n| y.include? n}
于 2012-01-30T04:37:00.597 に答える