범위 생성에서 '..'(이중 점)과 '…'(삼중 점)의 차이점은 무엇입니까?


111

방금 Ruby와 Ruby on Rails를 배우기 시작했고 범위를 사용하는 유효성 검사 코드를 발견했습니다.

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

첫번째 I에서 차이가 엔드 포인트의 포함에 줄 알았는데,하지만 난에 보였다 API 문서에, 그것이 여부 상관하는 것 같지 않았어요 .....: 그것은 항상 엔드 포인트를 포함.

그러나 irb에서 몇 가지 테스트를 수행했으며 ..두 끝점을 모두 ...포함하고 하한은 포함하고 상한은 포함하지 않는 것으로 나타났습니다 . 이 올바른지?

답변:


157

범위에 대한 문서는 이 말한다 :

..처음부터 끝까지 실행을 사용하여 구성된 범위 입니다. 사용하여 생성 된 항목 ...은 최종 값 을 제외합니다.

그래서 a..b같다 a <= x <= b반면 a...b같다 a <= x < b.


즉, 동안 참고 to_a정수의 집합을 제공 정수의 범위에, 레인지가 없는 값의 집합하지만, 시작 / 끝 값 단순히 한 쌍의 :

(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


이것을 포함하지 않았던 문서는 대신 Ranges에 대한 Pickaxe 섹션을 읽어야합니다 . 이 업데이트에 주목 해 주신 @MarkAmery ( 아래 참조 )에게 감사드립니다 .


11
더 나은 / 더 적은 위보다 예를 혼란 : (1..10).include? 10 #=> true(1...10).include? 10 #=> false
timmcliu

@timmcliu (a..b) != (a...(b+1))배열 표현이 같음에도 불구하고 (a, b ∈ ℤ 일 때) 요점을 설명하는 것과는 관련이 없습니다 . 나는 그것을 확장하기 위해 내 대답을 약간 업데이트했습니다.
Andrew Marshall

Range가 값 집합이 아닌 경우이 코드는 Range를 값 집합으로 취급하는 이유 : (1..5) .inject {| sum, n | sum + n}
VaVa

2
@ValentinVassilev Range는 값 집합이 아니지만 생성 할 수 있습니다. inject다음 EnumerableRange포함합니다. Enumerable활용 #each, 어떤 Range구현 . 에 의해 생성 된 목록 Range#eachRange객체 자체에 포함되지 않습니다 .
Andrew Marshall

6

맞아요.

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


12
점이 많을수록 범위가 더 적은 값을 의미 한다는 것이 정말 이상하다고 생각 합니다. 나는 그것이 ..더 일반적이며 덜 선호되는 것 같아요 ?
Andrew Marshall

2
@ 앤드류 : 저도 그렇게 생각했지만, 두 점으로 된 다양성이 더 일반적으로 원하고 따라서 타이핑이 더 짧아지는 것일까 요?
safetycopy

1
또한 (a..b-1) != (a...b)이 답변은 그렇다는 것을 의미하지만.
Andrew Marshall

1
(a..b-1) == (a ... b) a와 b가 정수이고 범위를 배열로 열거하는 경우에만 해당됩니다. 범위 (1.0 ... 3.5)를 고려하십시오-3.5 직전의 값은 무엇입니까? 확실히 2.5가 아닙니다!
Chris Heald

3

이제 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"] 

1

a...b 종료 값은 제외 하고 종료 값 a..b 은 포함 합니다.

정수로 작업 할 때 a...b처럼 동작 a..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
편집 후에도 여전히 올바르지 않습니다. 해도 ab정수의 범위는 다릅니다. 각각이 배열로 변환 될 때만 동일합니다. 수락 된 답변에는 특정 반례가 있습니다.
Andrew Marshall

2
@AndrewMarshall 내가 그 예에서 말하고자하는 것은 (분명히 잘하지는 않지만) 정수 척도에서 그렇게 작동한다는 것입니다. 답변에서 지적한 것처럼 더 정확한 분수 척도에서는 그렇지 않습니다. 나는 범위가 정수 척도로 가장 자주 사용된다고 생각한다. 이것이 내가 그러한 설명이 도움이된다고 믿는 이유이다.
Dennis

-4

.. 및 ...는 범위를 나타냅니다.

irb에서 확인하세요.

ruby-1.9.2-p290 :032 > (1...2).each do puts "p" end
p
 => 1...2 
ruby-1.9.2-p290 :033 > (1..2).each do puts "p" end
p
p

2
하지만 실제로 질문에 답하지는 않습니다. 둘 다 범위로 설명됩니다. 포괄적독점 범위.
Craig Ringer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.