我正在做一个编码谜题,其中你是一个矿工在一个数组中挖掘,但不能超出边界。我有如下代码:
if x > minemap.length-1 or x < 0 or y > minemap[0].length-1 or y < 0
return false
end
有没有更好、更干净、每行只有一个条件的方法来连接大量的OR语句?
我正在做一个编码谜题,其中你是一个矿工在一个数组中挖掘,但不能超出边界。我有如下代码:
if x > minemap.length-1 or x < 0 or y > minemap[0].length-1 or y < 0
return false
end
有没有更好、更干净、每行只有一个条件的方法来连接大量的OR语句?
首先,在 Ruby 中,条件语句中使用 or
和 and
而不是 ||
和 &&
是不符合惯用法的,因为它们具有不同的优先级,并且可能并不总是做你想要的事情(风格指南参考)。
至于实际问题,像这样的写法更符合 Ruby 的惯用法:
(0...minemap.length).cover?(x) && (0...minemap[0].length).cover?(y)
这段代码使用Range#cover?来检查x
和y
是否在正确的范围内,并且只有在这些条件为真时才返回false
。
return false
。 - Stefanreturn false
- 这可能是一个大方法内的检查。 - Stefan||=
将每个条件放在新行上:is_true = false # initial condition
is_true ||= x > minemap.length-1
is_true ||= x < 0
is_true ||= y > minemap[0].length-1
is_true ||= y < 0
is_true # will be true or false
# will return true or false
def out_of_bounds?
x > minemap.length-1 || x < 0 || y > minemap[0].length-1 || y < 0
end
def in_bounds?
!out_of_bounds?
end
unless x < 0 || y < 0 || minemap[x].nil? || minemap[x][y].nil?
# ...
end
如果您知道x和y始终为0或正数,则可以使用数学计算...
if (minemap.length - x) > 0 && (minemap[x].length - y) > 0
# ...
end
if x >=0 && y>= 0 && (minemap.length - x) > 0 && (minemap[x].length - y) > 0
# ...
end
祝你好运。
minemap
似乎是一个二维数组,因此 y
检查使用了 minemap[0].length]
。 - Michael Kohl(identical)
这个词。 :) - Michael Kohlminemap[-1]
进行了反向索引,而不是 nil
。 - Mirror318x < 0
检查轻松避免...但我认为 x < 0
可能是一个非法值,可以更早地检查并用于引发异常。该值应仅在出现错误或对应用程序进行攻击时出现。 - Myst我经常会利用any?
和all?
,使代码更具惯用性:
class Something
def the_question?
[ thing_1, thing_2, thing_3 ].any?
end
protected
def thing_1
# …
end
def thing_2
# …
end
def thing_3
# …
end
end
[]
方法,然后在其上调用了一个方法。换句话说,这个上下文/方法可能正在处理应该通过接口(而不是实现细节)与之交互的对象的细节。HEIGHT = 5
WIDTH = 10
@minemap = Array.new(WIDTH) { Array.new(HEIGHT) }
然后,我会使用between?
来检查x
和y
是否在范围内:
return unless x.between?(0, WIDTH-1) && y.between?(0, HEIGHT-1)
# do something with minemap[x][y]
顺便说一下,使用带有坐标键的哈希表通常比使用嵌套数组更容易,这样你就可以使用:minemap[x, y]
而不是minemap[x][y]
。
针对N个区间和N个相应点的最通用解决方案:
ranges = [0...minemap.length, 0...minemap[0].length]
values = [x, y]
ranges.zip(values).map { |e| e.reduce(&:cover?) }.all?
#⇒ true
您也可以明确查询第一个不适合的内容:
ranges.zip(values).detect { |e| !e.reduce(&:cover?) }
所有都不适合:
ranges.zip(values).reject { |e| e.reduce(&:cover?) }
etc.
[x > minemap.length-1, x < 0, y > minemap[0].length-1, y < 0].all?
这可能不是最好的或最惯用的方式,但值得一试。 - Santhoshif
语句经常出现在循环中(即检查板的状态)。这可能不像人们想象的那么小的优化。此外,许多开发人员声称Ruby很慢,我认为我们意识到有时我们的“惯用”方法实际上是性能瓶颈非常重要。人们没有像他们应该的那样经常考虑临时对象。 - Myst