Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby—Nice way to chain lots of OR statements? (checking against array out-of-bounds)

I am doing a coding puzzle where you are a miner in an array, and you can't be out of bounds. I have this code:

if x > minemap.length-1 or x < 0 or y > minemap[0].length-1 or y < 0
  return false
end

Is there a nicer/cleaner/one-thing-per-line way to chain lots of OR statements?

like image 668
Mirror318 Avatar asked Nov 17 '16 05:11

Mirror318


2 Answers

First off, use of or and and over || and && in conditions is not idiomatic in Ruby since they have different precedence and may not always do what you want (Style Guide reference). As for the actual question, something like this is more idiomatic Ruby:

(0...minemap.length).cover?(x) && (0...minemap[0].length).cover?(y)

This uses Range#cover? to check that x and y are inside the correct ranges and returns false unless that is true.

like image 83
Michael Kohl Avatar answered Sep 21 '22 10:09

Michael Kohl


Although I support @MichaelKohl's answer, it does create temporary objects since two range objects are allocated to the memory for each if statement and their #cover instance method is called.

These objects live in the memory waiting for the GC (garbage collector) do work it's magic and both their existence and their use waste resources and CPU cycles.

This might not be an issue, but it could degrade performance and it might become an issue when used within a loop or if the if statement is called often.

On the other hand...

IF you know that your array never contains nil (i.e., if the array contains valid true / false or other numeric values, you could simply use:

unless x < 0 || y < 0 || minemap[x].nil? || minemap[x][y].nil?
   # ...
end

Or IF you know both x and y are always 0 or positive, use math...

if (minemap.length - x) > 0 && (minemap[x].length - y) > 0
   # ...
end

Or use math with the added conditions...

if x >=0 && y>= 0 && (minemap.length - x) > 0 && (minemap[x].length - y) > 0
   # ...
end

Good luck.

like image 32
Myst Avatar answered Sep 21 '22 10:09

Myst