我无法理解以下代码:
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错误吗?
答案 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
,尝试访问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