Jeremy Flanagan Jeremy Flanagan - 5 months ago 17
Ruby Question

How do I convert nil to 0 in an array to get the sum?

Working on a version of Conway's Game of Life using 2d arrays and when trying too calculate the sum of each cell's "neighbors", I keeping getting blocked by the nil values.

def neighbor_count
grid.each_with_index do |row, idx|
row.each_with_index do |column, idx2|
[grid[idx - 1][idx2 - 1], grid[idx - 1][idx2], grid[idx - 1][idx2 + 1],
grid[idx][idx2 - 1], grid[idx][idx2], grid[idx][idx2 + 1],
grid[idx + 1][idx2 - 1], grid[idx + 1][idx2], grid[idx + 1][idx2 + 1]
].compact.sum

end
end
end


.compact seems to yield the most results if include "puts" in front of the array but none of the options I've tried give me 100%. I've tried reduce(:+), inject, .to_i, reject (to get rid of the nil values), and so forth.

What's missing here?

Error: world.rb:35:in
block (2 levels) in neighbor_count': undefined method
[]' for nil:NilClass (NoMethodError)

Line 35 is the line above ].compact.sum

Answer Source

nil values are only a symptom of the illness. Don't treat the symptoms, get rid of the problem! Which is that you are violating array bounds.

.each_with_index enumerates all indexes from the first to the last. And so idx + 1 on the last index will trigger this out-of-bounds situation. And idx - 1 on the first will produce an unexpected value instead of an error, which will impact your calculations. Good luck debugging that. :)

Put some guard checks in your code, to make sure you never go out of bounds.


Just to be absolutely clear, the problem is not that grid[idx + 1][idx2] is nil and messes up your calculations. It is that grid[idx + 1] is nil! And, naturally, you can't do nil[idx2]. That's the error.