Considering the following JSON example of logic, where when you see the value prop it is deriving its value from user input and comparing that against the expression:
{
"truthy": [
[
"AND",
{
"operator": "=",
"compareType": "text",
"value": "fname",
"expression": "John"
},
{
"operator": "=",
"compareType": "text",
"value": "lname",
"expression": "Doe"
}
],
"OR",
{
"operator": "=",
"compareType": "boolean",
"value": "Agree",
"expression": true
},
"OR",
[
"AND",
{
"operator": "=",
"compareType": "text",
"value": "fname",
"expression": "Jane"
},
{
"operator": "=",
"compareType": "text",
"value": "lname",
"expression": "Doe"
}
]
]
}
The translated expression would be:
(fname === "John" && lname === "Doe") || agree === true || (fname === "Jane" && lname === "Doe")
Right now what I'm doing is iterating over the structure and pushing values to an array, and later using eval to return true or false.
for (i; i < v.length; i++) {
if (Array.isArray(v[i])) {
e.push("(true===");
e.push(this.parseBlocks(v[i], a, 0));
e.push(")");
} else if (v[i] === "OR") {
e.push("||");
} else if (v[i] === "AND") {
e.push("&&");
} else {
e.push(true);
e.push("===");
e.push(this.parseBlocks([v[i]], a, 0));
}
}
return eval(e.join(""));
This works great, but was wondering if there would be a more precise way of handling this without building an expression to pass into eval?
The expression that the above code would generate if first name was John and last name was Doe and the checkbox (i.e. Agree) was not checked would be:
eval("(true === true) || true === false || (true === false)")
I didn't need to construct this string to evaluate when it was a simpler expression. For example, the two OR strings in between everything.
The code not included is the actual parsing function, but what it does is takes the first element in the array (i.e. "AND", "OR") and uses that to determine if that particular block of logic returns true or false.
How could this be handled with the consideration of potential deeper nesting of logic, to determine the outcome without using eval, or considering I'm controlling what's being passed into eval perhaps it may provide better performance in comparison?
Requirements:
- I need to keep the current JSON format of the actual conditions as previous functionality relies on it. The inclusion of "AND", "OR", how and where that is placed before, between, after, is optional as I try to find a more concise way of dealing with it.
- No, this cannot be done in SQL or other server-side methods
Inspiration:
- Found this which has a different structure but supports deeper nesting and complex structure so trying to understand how to adapt my existing solution to handle things similar.