Ruby Logic与Nil的比较

时间:2013-05-26 10:49:11

标签: ruby logic

我无法理解以下代码:

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

当我尝试在没有-1的情况下运行它时,我收到一个错误,说我无法将字符串与nil进行比较。但我不明白的是,为什么我们甚至需要-1? “......”游侠制造它所以我们只评估“a”,“e”,“i”,“o”(5个中的4个)。由于总长度为5,我们已经有4个要比较的东西,我的信念是比较(vowels_arr [i]&lt; = vowels_arr [i + 1])应该在没有-1的情况下工作。

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

还有其他方法在ruby中通过这个比较nil错误吗?

3 个答案:

答案 0 :(得分:2)

正因为如此:

vowels_arr[i + 1]

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

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

但是你要尝试从当前获得 next 索引。如果当前索引是最后一个索引(4),则会导致错误,因为您期望得到nil字符串(因为在不存在的索引处不存在元素)。这就是为什么你需要length - 1,以允许你的逻辑不要超出数组的范围。

顺便说一句,如果您正在尝试检查数组是否已排序,为什么不直接更新?

vowels_arr = ["a","e","i","o","u"]
puts vowels_arr.sort == vowels_arr 
# >> true

答案 1 :(得分:1)

正如Sergio的回答,问题在于vowels_arr[i + 1]。变量i的范围超过vowels_arr的索引,因此i + 1不一定指向现有的vowels_arr索引。特别是,当i到达最后一个索引时,i + 1将大于现有索引,vowels_arr[i + 1]将为nil

同样如Sergio的回答,如果你的目的是看它是否有分类,那么做Sergio的答案很简单,但在一般情况下,你可以这样做:

vowels_arr.each_cons(2).all?{|e1, e2| e1 <= e2}

答案 2 :(得分:-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,尝试访问5nil,就像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