【问题标题】:Evaluate many boolean expressions like Array#join in Ruby在 Ruby 中评估许多布尔表达式,例如 Array#join
【发布时间】:2012-12-28 23:36:29
【问题描述】:

在 Ruby 中,您可以使用 Array#join 通过可选的分隔符简单地将多个字符串连接在一起。

[ "a", "b", "c" ].join        #=> "abc"
[ "a", "b", "c" ].join("-")   #=> "a-b-c"

我想知道是否有很好的语法糖可以用一堆布尔表达式做类似的事情。比如我需要把&&一堆表达式放在一起。但是,将使用哪些表达式取决于用户输入。所以与其做一堆

cumulative_value &&= expression[:a] if user[:input][:a]

我想首先根据输入收集所有表达式,然后一举将&&它们全部收集在一起。比如:

be1 = x > y
be2 = Proc.new {|string, regex| string =~ regex}
be3 = z < 5 && my_object.is_valid?
[be1,be2.call("abc",/*bc/),be3].eval_join(&&)

默认情况下,Ruby 中有这样的设备吗?如果可能的话,我只是想要一些语法糖来使代码更干净。

【问题讨论】:

  • 您希望每个部分都接受参数并动态更改,还是它们是先前确定的?例如,be1 没有意义,除非已经给出 xy,在这种情况下,它将是 truefalse 的常量,但 be2 是一个 proc,它总是评估到一个真实的价值,这也是一个常数,除非你将它应用于一些论点,否则它没有多大意义。看来你正在混合这些。

标签: ruby syntactic-sugar boolean-expression


【解决方案1】:

试试Array#all?。如果arr 是一个布尔数组,它本身就可以工作:

arr.all?

如果arr 中的每个元素都为真,则返回true,否则返回false

您可以使用Array#any? 以相同的方式在|| 上加入数组,即如果数组中的任何元素为真则返回true,否则返回false

如果arrProcs 的数组,这也将起作用,只要您确保将正确的变量传递给块中的Proc#call(或使用类、实例或全局变量)。

【讨论】:

    【解决方案2】:

    您可以使用#all?#any?#none? 来实现:

    [true, false].any?
    => true
    
    [true, false].all?
    => false
    

    别忘了,除了nulfalse 之外的所有值都等于true

    ['', [], {}].all?
    => true
    

    【讨论】:

    • 太棒了!真的很高兴知道它。
    【解决方案3】:

    在这种特殊情况下,您只想根据用户选择的表达式过滤表达式哈希,然后测试所有这些表达式是否为真:

    cumulative_value = expression.select {|k, v| user[:input][k] }.values.all?
    

    这将首先从表达式中选择有匹配的user[:input] 键的所有成员,然后它将使用Array#all? 来测试所选表达式中的所有值是否为真。你的cumulative_value 要么是真的要么是假的。

    由于您的表达式值可能是 procs,因此您必须评估过滤后的表达式列表中的所有 procs,并从中构建一个结果数组,您可以调用 all? on:

    cumulative_value = expression.select {|k, v| user[:input][k] }.
      values.map {|value| value.is_a?(Proc) ? value.call : value }.all?
    

    几乎不是“语法糖”,但它可以完成工作而不会非常复杂。

    【讨论】:

      猜你喜欢
      • 2013-12-15
      • 2017-12-26
      • 1970-01-01
      • 2017-02-08
      • 1970-01-01
      • 1970-01-01
      • 2015-10-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多