PHP 如何计算递归 json 对象包含真值和假值
PHP How to evaluate a recursive json object contains true and false values
我正在开发一个 php 脚本,用于将对象评估为真或假。对象本身可以嵌套,包含很多对象,例如:
{
"nodeType": "and",
"0": {
"nodeType": "or",
"0": {
"nodeType": "or",
"1": false,
"2": true
},
"3": false
},
"4": true
}
前一个对象的计算结果应为真。也可以嵌套,例如:
{
"nodeType": "and",
"0": {
"nodeType": "or",
"0": {
"nodeType": "and",
"0": {
"nodeType": "or",
"1": false,
"2": true
},
"2": true
},
"3": false
},
"4": true
}
我已经有一个工作脚本,在 trincot 的帮助下运行良好脚本是:
public function findAnswer($expr) {
if (is_bool($expr)) return $expr; // Base case
// If OR, we can stop when we find true (and return true).
// If AND, we can stop when we find false (and return false).
// if($expr["nodeType"] == "not"){
// return ! $expr;
// }
if($expr["nodeType"] == "or"){
$search = true;
}
else{
$search = false;
}
foreach ($expr as $key => $value) {
if ($key !== "nodeType" && $this->findAnswer($value) === $search) {
return $search;
}
}
// If that never happened, return the opposite (false for OR, true for AND)
return !$search;
}
问题是当节点类型为 not
时,脚本无法运行。示例:
{
"nodeType": "and",
"0": {
"nodeType": "or",
"0": {
"nodeType": "not",
"1": false,
},
"3": false
},
"4": false
}
前一个对象的计算结果应为 false。
有什么建议可以改进脚本以与 not
nodeTypes 一起使用吗?
编辑:答案适用于某些情况,但不适用于以下情况:
{
"nodeType": "and",
"0": {
"nodeType": "or",
"0": {
"nodeType": "and",
"0": {
"nodeType": "not",
"1": true
},
"2": true
},
"3": false
},
"4": true
}
这被评估为真,而它应该被评估为假。
当运算符为“非”时,我们可以将其他参数视为 NAND 逻辑运算符的参数。因此,如果所有参数都是假的,那么它将被评估为真,否则为假。如果您永远不会将多个参数传递给 NOT 运算符,那么这并没有什么区别,但是当需要支持更多参数时,让它也可以与某些逻辑一起工作是很好的。
这是建议的代码:
public function findAnswer($expr) {
if (is_bool($expr)) return $expr; // Base case
// If OR, we can stop when we find true, and return true.
// If AND or NOT, we can stop when we find false,
// and return false or true respectively.
// If NOT, and multiple arguments, this performs like a NAND operator
$negate = $expr["nodeType"] == "not";
$search = $expr["nodeType"] == "or";
foreach ($expr as $key => $value) {
if ($key !== "nodeType" && $this->findAnswer($value) === $search) {
return $search !== $negate;
}
}
// If that never happened, return the opposite (false for OR, true for AND)
return $search === $negate;
}
我正在开发一个 php 脚本,用于将对象评估为真或假。对象本身可以嵌套,包含很多对象,例如:
{
"nodeType": "and",
"0": {
"nodeType": "or",
"0": {
"nodeType": "or",
"1": false,
"2": true
},
"3": false
},
"4": true
}
前一个对象的计算结果应为真。也可以嵌套,例如:
{
"nodeType": "and",
"0": {
"nodeType": "or",
"0": {
"nodeType": "and",
"0": {
"nodeType": "or",
"1": false,
"2": true
},
"2": true
},
"3": false
},
"4": true
}
我已经有一个工作脚本,在 trincot 的帮助下运行良好脚本是:
public function findAnswer($expr) {
if (is_bool($expr)) return $expr; // Base case
// If OR, we can stop when we find true (and return true).
// If AND, we can stop when we find false (and return false).
// if($expr["nodeType"] == "not"){
// return ! $expr;
// }
if($expr["nodeType"] == "or"){
$search = true;
}
else{
$search = false;
}
foreach ($expr as $key => $value) {
if ($key !== "nodeType" && $this->findAnswer($value) === $search) {
return $search;
}
}
// If that never happened, return the opposite (false for OR, true for AND)
return !$search;
}
问题是当节点类型为 not
时,脚本无法运行。示例:
{
"nodeType": "and",
"0": {
"nodeType": "or",
"0": {
"nodeType": "not",
"1": false,
},
"3": false
},
"4": false
}
前一个对象的计算结果应为 false。
有什么建议可以改进脚本以与 not
nodeTypes 一起使用吗?
编辑:答案适用于某些情况,但不适用于以下情况:
{
"nodeType": "and",
"0": {
"nodeType": "or",
"0": {
"nodeType": "and",
"0": {
"nodeType": "not",
"1": true
},
"2": true
},
"3": false
},
"4": true
}
这被评估为真,而它应该被评估为假。
当运算符为“非”时,我们可以将其他参数视为 NAND 逻辑运算符的参数。因此,如果所有参数都是假的,那么它将被评估为真,否则为假。如果您永远不会将多个参数传递给 NOT 运算符,那么这并没有什么区别,但是当需要支持更多参数时,让它也可以与某些逻辑一起工作是很好的。
这是建议的代码:
public function findAnswer($expr) {
if (is_bool($expr)) return $expr; // Base case
// If OR, we can stop when we find true, and return true.
// If AND or NOT, we can stop when we find false,
// and return false or true respectively.
// If NOT, and multiple arguments, this performs like a NAND operator
$negate = $expr["nodeType"] == "not";
$search = $expr["nodeType"] == "or";
foreach ($expr as $key => $value) {
if ($key !== "nodeType" && $this->findAnswer($value) === $search) {
return $search !== $negate;
}
}
// If that never happened, return the opposite (false for OR, true for AND)
return $search === $negate;
}