当我想要评估某个表达式时,我发现自己经常会看到一个模式,如果为true,则给出表达式的结果,或者如果为false则执行其他类似的表达式。例如
if hours.detect { |h| h.position > i && h.open == true }.nil?
hours.detect { |h| h.position >= 0 && h.open == true }
else
hours.detect { |h| h.position > i && h.open == true }
end
这段代码似乎很冗余。有人可以建议一种更优雅的方式吗?
谢谢!
答案 0 :(得分:2)
尝试代码:
hh = hours.select {|h| h.open == true }
hh.detect { |h| h.position > i } || hh.detect { |h| h.position >= 0 }
在大多数情况下(当h.open
返回一个布尔值时),它可以转换为以下一个:
hh = hours.select {|h| h.open }
hh.detect { |h| h.position > i } || hh.detect { |h| h.position >= 0 }
答案 1 :(得分:0)
我会这样做:
hh_true = hours.select {|h| h.open == true }
prc = prc hh_true.detect { |h| h.position >= 0 }
hh_true.detect(prc) { |h| h.position > i }
举例说明:
ary = ['fooo','fooo','foo']
prc = proc {ary.find{|e| e.size == 3}}
ary.detect(prc){|e| e.size == 5}
# => "foo"
ary.detect(prc){|e| e.size == 4 }
# => "fooo"
答案 2 :(得分:0)
您可以先创建方法
def detect_hours(i)
hours.detect { |h| h.position > i && h.open }
end
然后只使用下面的
detect_hours(i) || detect_hours(0)
答案 3 :(得分:0)
最直接的解决方案是:
hours.detect { |h| h.position > i && h.open == true } || \
hours.detect { |h| h.position >= 0 && h.open == true }
但它效率最高吗?乍一看,人们不会想到,最好先select
hours
h.open == true
detect
。但回想一下hours
一旦找到真实条件就退出,这可能是第一个块中hours
的第一个元素或第二个块中h.position > i
的最后一个元素。相对效率取决于数据。如果select
通常为真,则可能比首先执行hours
要快,这需要完全遍历&&
。如果效率很重要,可以对此进行测试,以及在每个块中反转两个{{1}} ed条件的效果。
答案 4 :(得分:0)
hours.sort! { |h1,h2|
((-1 if h1.open == false) || (1 if h1.position > i) || (0 if h1.position >= 0)) <=>
((-1 if h2.open == false) || (1 if h2.position > i) || (0 if h2.position >= 0))
}
hours[0] if hours[0].open
我认为这有效,但我不是百分百肯定。基本上,将hours
映射到一个数字,对这些数字进行排序,它将是第一个元素。
如果您不希望有任何h.position > i
个案例,这样会更好,因为您无论如何都必须检查整个阵列。
或者,虽然我不确定语法,但请使用ifnone
中的detect
功能:
hours.find(lambda{hours.find{|h| h.open && h.position > 0}}){|h| h.open && h.position > i}
答案 5 :(得分:0)
hours.detect { |h| h.position > i && h.open == true }
重复完全两次。在许多语言中,您可以将其存储到某个变量中:
var1 = hours.detect { |h| h.position > i && h.open == true }
然后在你的if中,你可以替换它:
if var1.nil?
hours.detect { |h| h.position >= 0 && h.open == true }
else
var1
end
您可以使用nil?
unless
var1 = hours.detect { |h| h.position > i && h.open == true }
unless var1
hours.detect { |h| h.position >= 0 && h.open == true }
else
var1
end
在此if中,hours.detect
完全相同。您可以将其提取到方法/ lambda / proc中。这是方法版本:
def hourse_detect hours, &lam # `&` change block of code into variable(`proc` / `lambda`) OR variable(`proc` / `lambda`) into block of code
hours.detect &lam #detect need block of code not `proc` / `lambda`
end
您可以存储{
和}
之间存在的代码块(或do
/ end
):
block1 = proc { |h| h.position > i && h.open == true }
block2 = proc { |h| h.position >= 0 && h.open == true }
以下是使用以上功能的完整代码:
def hourse_detect hours, &lam
hours.detect &lam
end
block1 = proc { |h| h.position > i && h.open == true }
block2 = proc { |h| h.position >= 0 && h.open == true }
var1 = hourse_detect hours, &block1
unless var1
hours_detect hours, &block2
else
var1
end
h.open == true
可以转换为:
def opened? hour
hours.open == true
end