Including an array of values โ€‹โ€‹and strings in an if statement in Javascript

I have an array like this:

[true, "&&", false]

True and false statements are generated by the previous conditions and placed in an array (I am trying to provide users with a way to create the main logic within my web project).

I cannot figure out how to turn this array into an actual if statement, which is executed as follows:

 if(true && false) { // Run Code } 

Note that depending on what the user has installed, the array may look like this:

[true, "||", false]

 if(true || false) { // Run code } 

I want to allow the array to also have parentheses:

["(", true, "&&", false, ")", "||", true]

should become:

 if( (true && false) || true) { // RUN CODE } 
+5
source share
3 answers

You can, although evil, use eval after connecting all the elements of the array. i.e.

 var arr = [true, '&&', false]; if(eval(arr.join(''))){ // your code } 

Update:

I recently thought of a very simple (no easier than eval) but safe answer. If the only logical operations you use are && and || , and parentheses are correctly formatted, you can replace regular expressions until only one value remains: "true" or "false".

Booleans for AND operations can only be as follows, and they simplify either true or false

true && true == true true && false == false false && true == false false && false == false

the same thing happens for OR operations

true || true == true true || false == true false || true == true false || false == false

As a result, we can replace the expression with our simplified values โ€‹โ€‹- true or false. Then, if there are parentheses around the expression, they will be either '(true)' or '(false)' , and we can also easily replace that expression.

Then we can loop this procedure until we are left with one value: 'true' or 'false' .

i.e. in code

 var boolArr = ["(", true, "&&", "(", false, "||", true, ")", ")", "||", true]; //Convert the array to a string "(true&&(false||true))||true" var boolString = boolArr.join(''); //Loop while the boolean string isn't either "true" or "false" while(!(boolString == "true" || boolString == "false")){ //Replace all AND operations with their simpler versions boolString = boolString.replace(/true&&true/g,'true').replace(/true&&false/g,'false'); boolString = boolString.replace(/false&&true/g,'false').replace(/false&&false/g,'false'); //Replace all OR operations with their simpler versions boolString = boolString.replace(/true\|\|true/g,'true').replace(/true\|\|false/g,'true'); boolString = boolString.replace(/false\|\|true/g,'true').replace(/false\|\|false/g,'false'); //Replace '(true)' and '(false)' with 'true' and 'false' respectively boolString = boolString.replace(/\(true\)/g,'true').replace(/\(false\)/g,'false'); } //Since the final value is a string of "true" or "false", we must convert it to a boolean value = (boolString == "true"?true:false); 

Annd, if you are really dangerous, you can tie all these replacements together

Also, pay attention to the wonderful lack of recursion and using only one loop

+7
source

What you want is a recursive descent parser .

The following code will handle true , false , && and || along with parentheses (which may be nested).

You can easily add other binary operators as needed.

 function process(logic) { var result, op, i, par, idx, token; for(i = 0; i < logic.length; i++) { token = logic[i]; if(token === '&&' || token === '||') { op = token; } else { if(token === '(') { for(par = 0, idx = i ; par ; idx++) { //handle nested parentheses if (logic[idx] === '(') par++; else if(logic[idx] === ')') par--; } token = process(logic.slice(i + 1, idx)); i = idx + 1; } if (op === '&&') result = result && token; else if(op === '||') result = result || token; else result = token; } }; return result; } //process function print(logic) { console.log(logic.join(' ') + ': ' + process(logic)); } print([true, "&&", false]); //false print([true, "&&", true]); //true print([false, "||", true]); //true print([false, "||", false]); //false print(["(", true, "&&", false, ")", "||", true]); //true print(["(", true, "&&", "(", false, "||", true, ")", ")", "||", true]); //true print([false, "||", "(", "(", true, "&&", "(", false, "||", true, ")", ")", "&&", false, ")"]); //false 
+7
source

Another solution is to build a nested array if parentheses exist, and with an object for operations that can be easily extended.

How it works:

Thermal iteration array and new array. For each new opening parenthesis, an empty array is assigned to the next level. All of the following terms are now taken to the next level.

If closing parentheses are found, the actual level is summed using calculate , and the result is transferred to the next lower level.

At the end, the base level is combined and the result is returned.

For evaluation, an object with functions for binary function symbols is used.

 function process(logic) { function calculate(a) { while (a.length > 2) { a.splice(0, 3, op[a[1]](a[0], a[2])); } return a[0]; } var op = { '&&': function (a, b) { return a && b; }, '||': function (a, b) { return a || b; } }, array = [[]], level = 0; logic.forEach(function (a) { if (a === '(') { ++level; array[level] = []; return; } if (a === ')') { --level; array[level].push(calculate(array[level + 1])); return; } array[level].push(a); }); return calculate(array[0]); } function print(logic) { document.write(logic.join(' ') + ': <strong>' + process(logic) + '</strong><br>'); } print([true, "&&", false]); //false print([true, "&&", true]); //true print([false, "||", true]); //true print([false, "||", false]); //false print(["(", true, "&&", false, ")", "||", true]); //true print(["(", true, "&&", "(", false, "||", true, ")", ")", "||", true]); //true print([false, "||", "(", "(", true, "&&", "(", false, "||", true, ")", ")", "&&", false, ")"]); //false 
+7
source

All Articles