0

我无法理解以下代码:

vowels_arr = ["a","e","i","o","u"]
(0...(vowels_arr.length - 1)).all? {|i| vowels_arr[i] <= vowels_arr[i + 1]}

当我尝试在没有 - 1 的情况下运行它时,我收到一条错误消息,指出我无法将字符串与 nil 进行比较。但我不明白的是为什么我们甚至需要-1?"..." ranger 使得我们只评估 "a","e","i","o" (5 个中的 4 个)。由于总长度是 5 并且我们已经有 4 个要比较的东西,我认为比较 (vowels_arr[i] <= vowels_arr [i+1]) 应该在没有 -1 的情况下工作。

有人可以向我解释为什么我们需要数组长度后的 -1 吗?

与零错误相比,红宝石还有其他方法可以克服这个问题吗?

4

3 回答 3

2

正因为如此:

vowels_arr[i + 1]

(0...(vowels_arr.length))将返回数组的所有索引。

(0...(vowels_arr.length)).to_a # => [0, 1, 2, 3, 4]

但是随后您正试图从 current.xml 获取下一个索引。如果当前索引是最后一个索引 (4),这会导致错误,因为您会到达nil期望字符串的位置(因为元素在不存在的索引处不存在)。这就是为什么您需要length - 1, 以允许您的逻辑不超出数组的范围。

顺便说一句,如果您要检查数组是否已排序,为什么不更直接地进行呢?

vowels_arr = ["a","e","i","o","u"]
puts vowels_arr.sort == vowels_arr 
# >> true
于 2013-05-26T10:57:12.787 回答
1

正如塞尔吉奥回答的那样,问题出在vowels_arr[i + 1]. 变量i范围在 的索引上vowels_arr,因此i + 1不一定指向 的现有索引vowels_arr。特别是,当i到达最后一个索引时,i + 1将大于现有索引,并且vowels_arr[i + 1]将为nil.

同样作为塞尔吉奥的回答,如果您的目的是查看它是否已排序,那么按照塞尔吉奥的回答很简单,但在一般情况下,您可以这样做:

vowels_arr.each_cons(2).all?{|e1, e2| e1 <= e2}
于 2013-05-26T11:52:58.267 回答
-1
vowels_arr = ["a","e","i","o","u"]
p vowels_arr[vowels_arr.length] #=> nil
(0..(vowels_arr.length)).all? {|i| vowels_arr[i] <= vowels_arr[i + 1]}
#=> `<=': comparison of String with nil failed (ArgumentError)

当您将vowels_arr[vowels_arr.length]元素传递给块时,即nil. 在Ruby数组中是0(zero)基于的。因此vowels_arr.length给出5意味着元素在 的范围内(0..4)。见下文:

vowels_arr = ["a","e","i","o","u"]
p vowels_arr[0] #=> "a"
p vowels_arr[1] #=> "e"
p vowels_arr[2] #=> "i"
p vowels_arr[3] #=> "o"
p vowels_arr[4] #=> "u"
p vowels_arr[5] #=> nil
p vowels_arr[6] #=> nil

(0..(vowels_arr.length))意味着您正在传递到块0,1,2,3,4,5,并且尝试访问5给出nil,就像在您的数组中的5th索引是nil. (0...(vowels_arr.length)).all? {|i| vowels_arr[i] <= vowels_arr[i + 1]}通过以下调试查看代码失败的原因,each以查看已传递给块的内容:

vowels_arr = ["a","e","i","o","u"]
(0...(vowels_arr.length)).each {|i| p vowels_arr[i],"--",vowels_arr[i+1]}
p (1...3).to_a

输出:

"a"
"--"
"e"
"e"
"--"
"i"
"i"
"--"
"o"
"o"
"--"
"u"
"u"
"--"
nil
于 2013-05-26T10:52:06.023 回答