这是我的代码:
class Train
attr_accessor :id, :person_id, :movie_id, :eval
def initialize(id, person_id, movie_id, eval)
@id = id
@person_id = person_id
@movie_id = movie_id
@eval = eval
end
end
trains = Array.new
CSV.open('train.csv', encoding: "BOM|UTF-16LE:UTF-8", row_sep: :auto, col_sep: ';') do |csv|
csv.each do |id, person_id, movie_id, eval|
trains[id.to_i] = Train.new(id.to_i, person_id.to_i, movie_id.to_i, eval.to_i)
end
end
trains.each do |t|
puts t.id
end
它只是从CSV文件创建一个对象数组,并打印对象的ID,但我收到一个错误:
undefined method `id' for nil:NilClass
当我使用t
打印对象时,为什么puts t
为零。
答案 0 :(得分:0)
您正在初始化数组,但随后通过指定索引添加到train数组。如果来自csv的id从1(或101)开始,则索引0到第一个将初始化为nil。
尝试使用trains <<
代替trains[id.to_i]
来填充数组。
编辑:
鉴于你的评论,我建议改用哈希。它们仍然是可枚举的,但通过这种方式,您可以自由迭代并使用id作为可访问的索引(键)。
trains = Hash.new
CSV.open('train.csv', encoding: "BOM|UTF-16LE:UTF-8", row_sep: :auto, col_sep: ';') do |csv|
csv.each do |id, person_id, movie_id, eval|
trains[id.to_i] = Train.new(id.to_i, person_id.to_i, movie_id.to_i, eval.to_i)
end
end
所以现在你有一个列车的哈希,火车ID作为钥匙。访问它仍然看起来像一个数组,但它会返回该对象。因此trains[5]
将返回id为5的Train
对象。
我认为这比使用带有一堆nils的数组更好。但是,如果你出于某些原因,只需在你的迭代中使用一个条件后的条件(虽然这真的很尴尬):
trains.each do |t|
puts t.id if t
end
在Ruby中,只有false和nil是“falsey”,意思是评估为false,这样就可以得到你想要的东西。但为了方便起见,我真的建议你去哈希路线。