web-dev-qa-db-ja.com

範囲生成における「..」(二重ドット)と「...」(三重ドット)の違いは?

Ruby and Ruby on Railsと範囲を使用する検証コードに出くわした:

validates_inclusion_of :age, :in => 21..99
validates_exclusion_of :age, :in => 0...21, :message => "Sorry, you must be over 21"

最初はエンドポイントを含めることに違いがあると思いましたが、調べたAPIドキュメントでは、それが..であるか...であるかは問題ではないようでした。常にエンドポイントが含まれていました。

ただし、irbでいくつかのテストを行ったところ、..には両方のエンドポイントが含まれ、...には下限のみが含まれ、上限は含まれないことが示されたようです。これは正しいです?

96
juil

範囲のドキュメント これを言う:

..を使用して構築された範囲は、最初から最後まで包括的に実行されます。 ...を使用して作成されたものは、終了値を除外します。

a..ba <= x <= bに似ていますが、a...ba <= x < bに似ています。


整数の範囲のto_aは整数のコレクションを提供しますが、範囲はnot値のセットですが、単に開始/終了値のペア:

(1..5).include?(5)           #=> true
(1...5).include?(5)          #=> false

(1..4).include?(4.1)         #=> false
(1...5).include?(4.1)        #=> true
(1..4).to_a == (1...5).to_a  #=> true
(1..4) == (1...5)            #=> false


これまでドキュメントには含まれていなかったため、代わりに Pickaxeの範囲に関するセクション を読む必要がありました。この更新に注意してくれた@MarkAmery( 以下を参照 )に感謝します。

144
Andrew Marshall

それは正しいです。

1.9.3p0 :005 > (1...10).to_a
 => [1, 2, 3, 4, 5, 6, 7, 8, 9]
1.9.3p0 :006 > (1..10).to_a
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

トリプルドット構文はあまり一般的ではありませんが、(1..10-1).to_a

5
Chris Heald

APIドキュメントでは、この動作について説明しています。

..を使用して構築された範囲は、最初から最後まで包括的に実行されます。 ...を使用して作成されたものは、終了値を除外します。

- http://Ruby-doc.org/core-2.1.3/Range.html

言い換えると:

2.1.3 :001 > ('a'...'d').to_a
 => ["a", "b", "c"] 
2.1.3 :002 > ('a'..'d').to_a
 => ["a", "b", "c", "d"] 
3
Mark Amery

a...bexcludes終了値、a..bincludes終了値。

整数を使用する場合、a...ba..b-1として動作します。

>> (-1...3).to_a
=> [-1, 0, 1, 2]

>> (-1..2).to_a
=> [-1, 0, 1, 2]

>> (-1..2).to_a == (-1...3).to_a
=> true

しかし、実際には範囲は 実数行 で異なります。

>> (-1..2) == (-1...3)
=> false

これは、小数ステップで増分するときに確認できます。

>> (-1..2).step(0.5).to_a
=> [-1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0]

>> (-1...3).step(0.5).to_a
=> [-1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, 2.5]
1
Dennis