我创建了一个为范围(1...array.length)
运行循环的方法。输出始终是正确的,长度大于1,但每当我只有一个字符i.e ['a']
的数组时,输出仍然正确。这让我担心的原因是因为我不确定程序如何知道在长度为1的情况下索引nil数组对象... arr[1]
。
def vowels_in_order?(word)
vowels = word.scan(/[aeiou]/)
(1...vowels.length).each { |index| return false if vowels[index] < vowels[index-1]}
return true
end
因此我想知道范围是否存在默认行为,这不会导致循环崩溃。或者可能,它与我的方法有关,因为这也是有洞察力的。
以下是循环技术崩溃的示例:
2.1.0 :1116 > word = "a"
=> "a"
2.1.0 :1117 > word[1] < word[0]
NoMethodError: undefined method `<' for nil:NilClass
from (irb#1):1117
答案 0 :(得分:3)
(1...1)
和(1...0)
都是空的(不包含任何元素),因此调用它们each
不会做任何事情。
答案 1 :(得分:2)
根据ruby documentation。有关范围的更详细文档(第一段应该对您有所帮助),请参阅该页面
Ranges constructed using .. run from the start to the end inclusively.
Those created using ... exclude the end value.
答案 2 :(得分:2)
让我们前往irb:
irb(main):001:0> (1...1).to_a
=> []
所以我们有一个空数组
现在让我们来看看你的代码
def vowels_in_order?(word)
vowels = word.scan(/[aeiou]/)
(1...vowels.length).each { |index| return false if vowels[index] < vowels[index-1]}
return true
end
这可以重写(对于vowels.length == 1):
def vowels_in_order?(word)
vowels = word.scan(/[aeiou]/)
[].each { |index| return false if vowels[index] < vowels[index-1]}
return true
end
您现在可以看到正在迭代一个空数组。因此,{ |index| return false if vowels[index] < vowels[index-1]}
块中的代码永远不会运行。我们可以用
irb(main):027:0> [].each { |i| puts "hello"}
=> []
已编辑:未发现您使用的是...
而非..
答案 3 :(得分:1)
使用Ranges时需要考虑以下事项。
这些是合理的范围声明:
(1 .. 1).to_a # => [1]
(1 .. 2).to_a # => [1, 2]
(1 ... 2).to_a # => [1]
请注意,1 .. 1
相当于1 ... 2
。
这些不是合理的范围声明,但结果相同:
(1 .. 0).to_a # => []
(1 ... 1).to_a # => []
而且,在这两种情况下,Ruby都不会做任何事情,因为范围必须以小于或等于结束值的起始值开始。
范围表示间隔 - 一组带有开头和结尾的值。范围可以使用s..e和s ... e literals构建,或者使用:: new构建。使用..构建的范围包括从开始到结束。使用...创建的那些排除了最终值。当用作迭代器时,范围将返回序列中的每个值。
......和......
... 将范围视为序列的方法(#each和从Enumerable继承的方法)期望begin对象实现succ方法以按顺序返回下一个对象。
1.succ # => 2
会立即导致范围内的迭代退出。
使用..
而不是...
。由于...
的行为等效行为1 ... 2
,(1) .. (2 - 1)
是许多错误和维护问题的根源。人们的目光很快就能看到和识别何时使用...
代替..
。 IF 你坚持使用...
,然后格式化你的代码以获取合法性,并使用空格给眼睛一些东西。
1 .. 1
比以下内容更具可读性:
1..1
或:
1...2
答案 4 :(得分:-1)
我假设您对创建范围的语法a...b
实际上做了什么有一些误解。请查看range,其中解释了此语法。
范围表示间隔 - 一组带有开头和结尾的值。范围可以使用s..e和s ... e literals构建,或者使用:: new构建。使用..构建的范围包括从开始到结束。使用...创建的那些排除了最终值。当用作迭代器时,范围将返回序列中的每个值。
(-1..-5).to_a #=> []
(-5..-1).to_a #=> [-5, -4, -3, -2, -1]
('a'..'e').to_a #=> ["a", "b", "c", "d", "e"]
('a'...'e').to_a #=> ["a", "b", "c", "d"]