简体   繁体   English

Ruby Logic与Nil的比较

[英]Ruby Logic comparisons with Nil

I am having trouble understanding the following code: 我无法理解以下代码:

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

When I try to run it WITHOUT the - 1, I get an error saying that I can't compare a string to nil. 当我尝试在没有-1的情况下运行它时,我得到一个错误,说我无法将字符串与nil进行比较。 But what I dont understand is that why do we even need the -1?? 但我不明白的是,为什么我们甚至需要-1? The "..." ranger makes it so we are only evaluating "a","e","i","o" (4 out of the 5). “......”游侠制造它所以我们只评估“a”,“e”,“i”,“o”(5个中的4个)。 Since the total length is 5 and we are already at 4 things to compare, my belief is that the comparison (vowels_arr[i] <= vowels_arr [i+1]) should work without the -1. 由于总长度为5,我们已经有4个要比较的东西,我的信念是比较(vowels_arr [i] <= vowels_arr [i + 1])应该在没有-1的情况下工作。

Can someone please explain to me why we need the -1 after array length? 有人可以向我解释为什么我们需要数组长度后的-1?

Also are there other ways in ruby to get past this comparing to nil error? 还有其他方法在ruby中通过这个比较nil错误吗?

It's because of this: 这是因为:

vowels_arr[i + 1]

(0...(vowels_arr.length)) will return all indexes for the array. (0...(vowels_arr.length))将返回数组的所有索引。

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

But then you're trying to get next index from current. 但是那时你正试图从当前的下一个索引。 If current index is last index (4), this results in an error, because you get nil where you expect a string (because element doesn't exist at non-existent index). 如果当前索引是最后一个索引(4),则会导致错误,因为在期望字符串的位置会得到nil (因为在不存在的索引处不存在元素)。 That's why you need length - 1 , to allow your logic not to go out of array's bounds. 这就是为什么你需要length - 1 ,以允许你的逻辑不要超出数组的界限。

By the way, if you're trying to check if the array is sorted, why not do it more directly? 顺便说一句,如果您正在尝试检查数组是否已排序,为什么不直接更新?

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

As Sergio answers, the problem is with vowels_arr[i + 1] . 正如塞尔吉奥所回答的,问题在于vowels_arr[i + 1] The variable i ranges over the indices of vowels_arr , and hence i + 1 will not necessarily point to an existing index of vowels_arr . 变量i范围超过了vowels_arr的索引,因此i + 1不一定指向现有的vowels_arr索引。 Particularly, when i reaches the last index, i + 1 will be greater than the existing indices, and vowels_arr[i + 1] will be nil . 特别是,当i到达最后一个索引时, i + 1将大于现有索引,并且vowels_arr[i + 1]nil

Also as Sergio answers, if your purpose is to see if it is sorted, then doing as Sergio's answer is straightforward, but in general cases, you can do it like this: 也正如塞尔吉奥所回答的那样,如果你的目的是看它是否有分类,那么像塞尔吉奥那样做的答案很简单,但在一般情况下,你可以这样做:

vowels_arr.each_cons(2).all?{|e1, e2| e1 <= e2}
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)

As you are passing the vowels_arr[vowels_arr.length] element to the block,which is nil . 当你将vowels_arr[vowels_arr.length]元素传递给块时,它是nil In Ruby array's are 0(zero) based. Ruby数组中,基于0(zero) Thus vowels_arr.length gives 5 means elements are in the range of (0..4) . 因此, vowels_arr.length给出5均值元素在(0..4)的范围内。 see below: 见下文:

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)) means you are passing to the block 0,1,2,3,4,5 , and an attempt to access 5 gives nil , as in your array in 5th index is nil . (0..(vowels_arr.length))表示你正在传递给块0,1,2,3,4,5 ,并且尝试访问5给出nil ,因为在5th索引中的数组中为nil See why the code (0...(vowels_arr.length)).all? {|i| vowels_arr[i] <= vowels_arr[i + 1]} 看看为什么代码(0...(vowels_arr.length)).all? {|i| vowels_arr[i] <= vowels_arr[i + 1]} (0...(vowels_arr.length)).all? {|i| vowels_arr[i] <= vowels_arr[i + 1]} (0...(vowels_arr.length)).all? {|i| vowels_arr[i] <= vowels_arr[i + 1]} failed by the below debugging with each to see what has been passed to the block: (0...(vowels_arr.length)).all? {|i| vowels_arr[i] <= vowels_arr[i + 1]}通过以下调试失败, each调试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

Output: 输出:

"a"
"--"
"e"
"e"
"--"
"i"
"i"
"--"
"o"
"o"
"--"
"u"
"u"
"--"
nil

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM