2012-03-13 67 views
75

Tôi vừa mới bắt đầu học Ruby và Ruby on Rails và đã xem qua mã xác nhận có sử dụng các dãy:Sự khác biệt giữa '..' (dấu chấm kép) và '...' (dấu ba chấm) trong thế hệ dải?

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

Lúc đầu, tôi nghĩ rằng sự khác biệt là trong sự bao gồm thiết bị đầu cuối, nhưng trong các tài liệu API Tôi nhìn vào , nó không có vẻ quan trọng cho dù đó là .. hoặc ...: nó luôn bao gồm các điểm cuối.

Tuy nhiên, tôi đã thực hiện một số thử nghiệm trong IRB và dường như chỉ ra rằng .. bao gồm cả hai điểm cuối, trong khi ... chỉ bao gồm giới hạn dưới nhưng không bao gồm giới hạn trên. Điều này có đúng không?

Trả lời

111

Các documentation for Range nói điều này:

Phạm vi xây dựng bằng .. chạy từ đầu đến cuối inclusively. Những người được tạo bằng cách sử dụng ... loại trừ giá trị kết thúc.

Vì vậy a..b là như a <= x <= b, trong khi a...b là như a <= x < b.


Lưu ý rằng, trong khi to_a trên một dãy các số nguyên cho một tập hợp các số nguyên, một dãy là không một tập hợp các giá trị, nhưng chỉ đơn giản là một cặp giá trị bắt đầu/kết thúc:

(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 


Tài liệu được sử dụng để không bao gồm tài liệu này, thay vì yêu cầu đọc Pickaxe’s section on Ranges. Nhờ @MarkAmery (see below) để lưu ý cập nhật này.

+0

Tôi đã lập trình ruby ​​được 8 năm và không bao giờ biết điều này. Cảm ơn! –

+9

Ví dụ tốt hơn/ít khó hiểu hơn ví dụ trên: '(1..10) .include? 10 # => true' và '(1 ... 10) .bao gồm? 10 # => false' – timmcliu

+0

@timmcliu Mặc dù không liên quan đến việc minh họa điểm mà '(a..b)! = (A ... (b + 1))' mặc dù biểu diễn mảng của chúng bằng nhau (khi a, b ∈ ℤ). Tôi đã cập nhật câu trả lời của mình một chút để mở rộng. –

4

Điều đó là chính xác.

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] 

Cú pháp triple-dot ít phổ biến hơn, nhưng đẹp hơn (1..10-1).to_a

+9

Tôi nghĩ thật kỳ lạ rằng * nhiều * dấu chấm nghĩa là phạm vi biểu thị * ít hơn * giá trị. Tôi đoán nó chỉ là '..' là phổ biến hơn và do đó ít được ưa thích cho nó? –

+2

@Andrew: Tôi cũng nghĩ như vậy, nhưng có lẽ nó thuộc loại đa điểm được ưa chuộng hơn và do đó ngắn hơn? – safetycopy

+0

Ngoài ra, lưu ý rằng '(a..b-1)! = (A ... b)', mặc dù câu trả lời này ngụ ý chúng là. –

-4

.. và ... biểu thị một loạt.

Chỉ cần nhìn thấy nó trong 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

Không thực sự trả lời câu hỏi, mặc dù; cả hai được mô tả là phạm vi. * Bao gồm * vs * Exclusive * phạm vi. –

3

Các tài liệu API nay mô tả hành vi này:

Phạm vi xây dựng bằng .. chạy từ đầu đến cuối inclusively. Những người được tạo bằng cách sử dụng ... loại trừ giá trị kết thúc.

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

Nói cách khác:

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...bkhông bao gồm giá trị kết thúc, trong khi a..bbao gồm giá trị kết thúc.

Khi làm việc với số nguyên, a...b hoạt động như 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 

Nhưng phạm vi thực sự khác nhau trên real number line.

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

Bạn có thể thấy điều này khi tăng dần theo các bước phân đoạn.

>> (-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] 
+0

Không đúng. 'a ... b' là * không * bằng' a .. (b-1) '. –

+0

Vẫn không chính xác sau khi chỉnh sửa. Ngay cả khi 'a' &' b' là các số nguyên, các phạm vi khác nhau. Chỉ khi mỗi được chuyển đổi thành một mảng thì chúng giống nhau. Một ví dụ cụ thể tồn tại trong câu trả lời được chấp nhận. –

+2

@AndrewMarshall Những gì tôi có nghĩa là để nói với ví dụ đó (nhưng không phải là rất rõ ràng) là trên một quy mô số nguyên nó cư xử theo cách đó. Đây không phải là trường hợp trên thang phân số chính xác hơn, như được chỉ ra trong câu trả lời của bạn. Tôi nghĩ phạm vi thường được sử dụng trên một quy mô số nguyên mặc dù, đó là lý do tại sao tôi tin rằng một lời giải thích như vậy là hữu ích. – Dennis

Các vấn đề liên quan