エンドポイントの一方または両方を除外する範囲をrubyで作成することは可能ですか?では、開区間と閉区間の境界の数学でこの概念を処理するのでしょうか。
たとえば、1.0を除く1.0〜10.0の範囲を定義できますか?
言う(疑似ルビーで)
range = [1.0...10.0)
range === 1.0
=> false
range === 10.0
=> true
エンドポイントの一方または両方を除外する範囲をrubyで作成することは可能ですか?では、開区間と閉区間の境界の数学でこの概念を処理するのでしょうか。
たとえば、1.0を除く1.0〜10.0の範囲を定義できますか?
言う(疑似ルビーで)
range = [1.0...10.0)
range === 1.0
=> false
range === 10.0
=> true
RubyのRange
クラスは、閉じた範囲と半分開いた(右開いた)範囲のみをサポートします。ただし、自分で簡単に書くことができます。
Rubyのハーフオープンレンジの例を次に示します。
range = 1.0...10.0
range === 1.0
# => true
range === 10.0
# => false
Range
RubiniusのRuby1.9準拠クラスの合計行数は、 238行のRubyコードです。Ruby言語仕様のすべてのしわ、コーナーケース、特殊なケース、特異性、下位互換性の癖などをサポートするためにオープンレンジクラスが必要ない場合は、それよりもはるかに少ない数で解決できます。
本当に包含をテストする必要があるだけの場合は、次のようなもので十分です。
class OpenRange
attr_reader :first, :last
def initialize(first, last, exclusion = {})
exclusion = { first: false, last: false }.merge(exclusion)
@first, @last, @first_exclusive, @last_exclusive = first, last, exclusion[:first], exclusion[:last]
end
def first_exclusive?; @first_exclusive end
def last_exclusive?; @last_exclusive end
def include?(other)
case [first_exclusive?, last_exclusive?]
when [true, true]
first < other && other < last
when [true, false]
first < other && other <= last
when [false, true]
first <= other && other < last
when [false, false]
first <= other && other <= last
end
end
alias_method :===, :include?
def to_s
"#{if first_exclusive? then '(' else '[' end}#@first...#@last#{if last_exclusive? then ')' else ']' end}"
end
alias_method :inspect, :to_s
end
範囲の右端の要素は。で除外できます...
。以下の例を参照してください
(1..10).to_a # an array of numbers from 1 to 10 - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
(1...10).to_a # an array of numbers from 1 to 9 - [1, 2, 3, 4, 5, 6, 7, 8, 9]
実行を使用して構築された範囲..
は、最初から最後まで包括的に実行されます。を使用して作成されたものは...
、最終値を除外します。
('a'..'e').to_a #=> ["a", "b", "c", "d", "e"]
('a'...'e').to_a #=> ["a", "b", "c", "d"]
詳細はこちら
開始値を除外する独自の範囲を簡単に作成することもできます。
フロート範囲の場合:
(1.0..10.0).step.to_a # => [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
(1.0...10.0).step.to_a # => [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
(1.0..10.0).step(2.0).to_a # => [1.0, 3.0, 5.0, 7.0, 9.0]
(1.0...10.0).step(2.0).to_a # => [1.0, 3.0, 5.0, 7.0, 9.0]
数年後ですが...caseステートメントが各基準を出現順に評価し、最初の一致に基づいてパスをたどるという事実を利用するのはどうでしょうか。サンプル1.0では、技術的には2番目の「when」の有効な値であっても、常に何も実行されません。
case myvalue
when 1.0
#Don't do anything (or do something else)
when 1.0...10.0
#Do whatever you do when value is inside range
# not inclusive of either end point
when 10.0
#Do whatever when 10.0 or greater
end