范围生成中“ ..”(双点)和“…”(三点)之间的区别?


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"

起初我以为差异的包容端点,但在API文档我进去看了看,它并似乎并不重要,是否是.....:它总是包括端点。

但是,我在irb中进行了一些测试,它似乎表明..包括两个端点,而...仅包含了下限,而没有包含上限。这样对吗?

Answers:


157

Range 文档说:

使用..run 构造的范围从开始到结束。使用创建...的值不包括最终值。

所以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∈hen时)无关,但并不重要。我已经对我的答案做了一些更新,以扩大其范围。
安德鲁·马歇尔

如果Range不是一组值,那么为什么这段代码将Range视为一组值:(1..5).inject {| sum,n | sum + n}
VaVa

2
@ValentinVassilev Range不是一组值,但是可以生成它们。inject来自Enumerable其中RangeEnumerable利用#eachRange实现。生成的列表Range#each从不包含在Range对象本身内。
安德鲁·马歇尔

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
我认为奇怪的是,更多的点表示范围代表更少。我想这只是..更普遍,因此更受欢迎吗?
安德鲁·马歇尔

2
@安德鲁:我也这么认为,但是也许是由于人们更希望使用两点式字体,从而缩短了字体?
safetycopy 2012年

1
另外,请注意(a..b-1) != (a...b),尽管此答案暗示它们是。
安德鲁·马歇尔

1
(a..b-1)==(a ... b)仅在a和b为整数并且将范围枚举为数组的情况下。考虑范围(1.0 ... 3.5)-3.5之前的值是多少?当然不是2.5!
克里斯·希尔德


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是整数,范围也不同。只有当每个都转换为数组时,它们才是相同的。接受的答案中存在特定的反例。
安德鲁·马歇尔

2
@AndrewMarshall在这个示例中我想说的(但显然不是很清楚)是在整数范围内,它的行为方式如此。正如您的答案所指出的,在更精确的分数范围上并非如此。我认为范围是最常用的整数范围,这就是为什么我认为这样的解释会有所帮助。
丹尼斯

-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 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.