鉴于以下内容:
def test(arr)
cache = []
for i in 0..arr.length
if !cache[arr[i]] # no implicit conversion from nil to integer
cache[arr[i]] = true
end
if !cache[arr[i]].to_i # no implicit conversion from nil to integer
cache[arr[i]] = true
end
if !cache[arr[i].to_i] # works fine
cache[arr[i]] = true
end
end
end
puts test([1, 5, 8, 11])
为什么cache[arr[i]]
需要进行to_i
转换?来自this answer
您的错误来自Ruby解释器中的C代码。用C语言实现的核心类在需要Integer时会被赋予nil。它可能有#to_i但它没有#to_int,因此结果是TypeError。
我不知道转换arr[i].to_i
如何解决错误,因为arr[i]
已经是整数?
答案 0 :(得分:4)
您在这里遇到麻烦主要是因为您正在使用for
,而且您使用不当。尽管很奇怪,for
几乎没有在Ruby中使用过。相反,鼓励使用each
和其他可枚举变体。
这是您的代码的Ruby惯用版本:
def test(arr)
cache = [ ]
arr.each_with_index do |e, i|
cache[i] = true
end
cache
end
如果您正在进行索引不相关的简单转换,您甚至可以进一步重构:
def test(arr)
arr.map do |e|
true
end
end
如果您在循环的每次迭代中检查了i
假设的值,那么您会看到它越过数组的末尾,因此最终从外部返回nil
of-bounds电话。 .to_i
将此转换回0
,这会解决问题,但无法解决问题。
如果您想使用0...arr.length
运算符前往但结尾限制<{1>}的范围,请使用...
。
答案 1 :(得分:2)
您的问题可能是由于迭代超过输入数组末尾的事实。
0..arr.length将为您的测试示例处理0,1,2,3,4的索引。该数组的最后一个元素的索引为3.
我相信你想要0 ... arr.length让这更有意义。
请注意第二个例子中的......和你的.. ..
答案 2 :(得分:2)
您正在访问一个不存在的元素:第一个索引为0,最后一个索引为length-1
,ergo arr[arr.length]
不存在并返回{{1} },这意味着nil
是cache[arr[arr.length]]
,并且由于cache[nil]
是一个数组,而数组是由整数索引的,它会尝试使用{{1}将cache
转换为整数但是失败了。
立即解决方法是不要迭代到nil
,方法是将包含范围构建到to_int
或使用排他范围。
但是真正的答案是,无论何时编写循环,你都会做错事,arr.length
API中有一个方法,你宁愿使用它。不幸的是,从你的代码中可以清楚地知道它应该做什么,现在它只是返回范围并且没有副作用,所以它几乎什么都不做。
这是你在找什么?
arr.length-1