>我有一个布尔值数组,true
或false
用字符串分隔,这些字符串表示逻辑运算符||
或&&
,例如:
[true, "||", false, "&&", true]
数组大小不是固定的。我想[true, "||", false]
评估前三个元素,并评估结果加上数组的其余艺术。
我正在考虑使用:
array.each_slice(3).to_a.reduce
但我不确定在reduce
块中传递什么。这里需要一些方向。
代码
def evaluate(arr)
pairs = arr.drop(1).each_slice(2)
pairs.reduce(arr.first) { |rv, (op, bool)| op == '&&' ? rv && bool : rv || bool }
end
例子
evaluate [true, '&&', false, '||', true] #=> true
evaluate [false, '||', true, '&&', false] #=> false
解释
假设
arr = [true, '&&', false, '||', true]
然后
a = arr.drop(1) #=> ["&&", false, "||", true]
pairs = a.each_slice(2) #=> #<Enumerator: ["&&", false, "||", true]:each_slice(2)>
我们可以看到枚举器pairs
通过将块转换为数组来发送到块的元素。
pairs.to_a #=> [["&&", false], ["||", true]]
继续(rv
是返回值的缩写(,我们生成pairs
的第一个元素,将其传递给块并将值分配给块变量op
并bool
。
rv = arr.first #=> true
op, bool = pairs.next #=> ["&&", false]
op #=> "&&"
bool #=> false
我们现在执行块计算。如
op == '&&' #=> true
该块计算并返回以下内容,即备忘录的新值,rv
:
rv && bool #=> true && false => false
我们现在生成pairs
的第二个也是最后一个元素,将其传递给块,为块变量赋值(回想一下rv
现在等于false
(并执行块计算。
op, bool = pairs.next #=> ["||", true]
op #=> "||"
bool #=> true
op == '&&' #=> false
rv || bool #=> false || true #=> true
因此,该方法返回true
.
改用内核#eval
如果我们信任数组中的值,我们可以简单地写入
eval [true, '&&', false, '||', true].join #=> true
eval [false, '||', true, '&&', false].join #=> false
使用eval
将允许我们添加"("
,")" and
"!' 到数组中,大大增加了可以(轻松(计算的布尔表达式的范围。