如何在JSON中稳健地描述带有AND、OR条件表达式?

13

假设我有一个表达式:

( A >= 10 && B == 20 ) || ( C < 30 ) || ( D != 50 )

我建议使用以下JSON来存储/表示这个表达式:

{ "filter": 
    [
        { "var":"A", "condition":"ge", "num":10 },
        { "var":"B", "condition":"e", "num":20 }
    ],
    [
        { "var":"C", "condition":"lt", "num":30 }
    ],
    [
        { "var":"D", "condition":"ne", "num":50 }
    ]
}

“filter”映射到一个子数组的数组。每个子数组中的所有元素都与AND相关联,而所有子数组都与OR相关联。

在这样编写JSON时,我是否忽视了什么?


在JSON中表示似乎非常不错。 - Thom Wiggers
3
如果你有 A < B?或者甚至是 10 < A?顺序是什么? - Reut Sharabani
1个回答

15

你在这里做出了几个假设:

  1. 比较将始终在变量和数字之间进行,而不是在两个变量或两个数字之间进行。
  2. 变量将始终位于比较的左侧,数字位于右侧。

对于您特定的用例,这些假设可能是正确的,但更具未来性的方法是像处理带参数的函数一样处理比较:

{ "ge": ["A", 10] }

此外,虽然你使用对象数组来表示AND和数组数组来表示OR的想法很巧妙,但对于编写代码进行解析的人来说可能不是立即明显的。重新使用对象的想法,其中键表示函数及其关联值为参数更具表现力:

{ "all": [<condition 1>, <condition 2>, ...] }

将这两个想法结合起来,我们得到了类似于这样的东西:

{ "any": [
    { "all": [
        { "ge": ["A", 10] },
        { "eq": ["B", 20] }
    ]},
    { "lt": ["C", 30] },
    { "ne": ["D", 50] }
]}

1
我喜欢使用“任何”和“或”来表示“或”和“和”运算符。如果需要,也可以引入“无”。如果它只有一个子节点,“无”将完成“非”的工作;如果有多个子节点,“无”将完成“或”的工作。 - Wayne Conrad
1
谢谢,Zero!它很干净高效。使用关键字“any”和“all”,编写递归解析JSON的代码非常容易。 - lichgo
@lichgo 这是以这种方式编写的另一个有用的功能,是的 :-) 很高兴听到我的答案对你有帮助... - Zero Piraeus
1
这基本上是javascript包json-logic使用的格式。此格式还有可用于php和python的解析器。 - josteinb
好吧,这样啊...谢谢 @josteinb :-) 我认为需要稍加注意,因为 Python 和 JS 版本会根据每种语言对等式和标识的定义而对 ===== 进行不同的解释。我能想象到这个问题可能会导致难以发现的错误,这让我有点担心。 - Zero Piraeus
MongoDB表达式语法 https://docs.mongodb.com/manual/reference/operator/query/ - Palani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接