Разница между '..' (двойная точка) и '...' (тройная точка) в генерации диапазона? - PullRequest
94 голосов
/ 13 марта 2012

Я только начал изучать 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"

Сначала я подумал, что разница заключалась во включении конечных точек, но в документах API, которые я изучал, не имело значения, было ли это .. или ...: оно всегда включало конечные точки.

Тем не менее, я провел некоторое тестирование в irb, и оно показало, что .. включает обе конечные точки, тогда как ... включает только нижнюю границу, но не верхнюю. Это правильно?

Ответы [ 5 ]

142 голосов
/ 13 марта 2012

Документация для Range гласит:

Диапазоны, построенные с использованием .., проходят от начала до конца включительно. Созданные с использованием ... исключают конечное значение.

Так что 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


Документы, которые раньше не включали это, вместо этого требовали прочтения раздела Кирки в диапазонах . Спасибо @MarkAmery ( см. Ниже ) за то, что отметили это обновление.

5 голосов
/ 13 марта 2012

Это правильно.

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

3 голосов
/ 09 октября 2014

Документы 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 голос
/ 15 января 2015

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]
0 голосов
/ 13 марта 2012

.. и ... обозначают диапазон.

Просто посмотрите в 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
...