Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

185
Views
Build boolean expression from arrays and evaluate entire expression at one time in javascript

I have two arrays - one that contains booleans, and the other operators:

to_eval = [true, true, false, false]
ops=['&&', '||', '&&']

Out of this I'd like to build an expression

result = true && true || false && false

Which should evaluate to true based on precedence rules

If I iterate over the arrays evaluating as I go, the result is false.

I could build a string and use Eval or Function - but from what I have been reading this can cause security issues in a web application.

Is there a way in Javascript to build out an expression without evaluating it till it is fully formed so that precedence rules are observed without using Eval or Function?

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

You can create a mapping functions for the trusted logic operators safely with Array#reduce:

But the way this evaluates from left to right without precedences, so true && true || false && false will evaludate false. If you want more accurate result like how JavaScript parse things, it would be easier to use eval with proper sanitization.

const to_eval = [true, true, false, false];
const ops = ['&&', '||', '&&'];

const ops_map = {
  '&&': (a, b) => a && b,
  '||': (a, b) => a || b
};

const result = to_eval.reduce((acc, cur, i) => ops_map[ops[i-1]](acc, cur));

console.log(result);

With proper santization, you can safely use eval:

const evaluate = (to_eval, ops = []) => {
  const expression = to_eval.reduce((acc, cur, i) => {
    let left = i === 1 ? !!acc : acc;
    let op = {'&&': '&&', '||': '||'}[ops[i-1]];
    if(typeof op !== 'string') {
      op = '||';  // fallback
    }
    let right = !!cur;
    
    return `${left} ${op} ${right}`
  });
  const result = eval(expression);
  console.log(expression, ' => ', result);
  return result;
}

const to_eval = [true, true, false, false]
const ops = ['&&', '||', '&&'];
evaluate(to_eval, ops);

evaluate([true], []);

evaluate(['alert(1)', 0, false], ['alert(2)', 'hasOwnProperty']);

about 4 years ago · Juan Pablo Isaza Report

0

You can safely call eval, if it is certain that your two arrays have the expected values (booleans and expected operators). So just add some code to verify the two given inputs.

You can do as follows:

function evaluate(bools, ops) {
    // Verify the given arguments are as expected
    if (!ops.every(op => ["&&", "||"].includes(op))) throw "invalid operator";
    if (!bools.every(bool => typeof bool === "boolean")) throw "invalid operand";
    if (bools.length !== ops.length + 1) throw "length mismatch";
    return eval(bools.map((bool, i) => bool + " " + (ops[i] ?? "")).join(" "));
}

let to_eval = [true, true, false, false];
let ops = ['&&', '||', '&&'];
let result = evaluate(to_eval, ops);
console.log(result);

about 4 years ago · Juan Pablo Isaza Report

0

You could use eval if you sanitize the input (IE, verify that all the tokens are from a very specific list of allowed tokens).

function safeEval(expression) {
    const allowed = ['true', 'false', '&&', '||'];
    if (expression.split(/\s+/).every(token => allowed.includes(token))) {
        return eval(expression);
    } else {
        throw Error('Encountered forbidden token.');
    }
}

console.log(safeEval('true && true || false && false'));
console.log(safeEval('undefined'));

This is far from the most efficient code you could write, but it's simple and gets the job done, and adding support for other operators and parentheses is trivial.

Alternatively, you could evaluate the operators yourself, in the order of precedence you desire:

const expression = [true, '&&', true, '||', false, '&&', false];

for (let i = 0; i < expression.length; ++i) {
    if (expression[i] === '&&') {
        const left = expression[i - 1];
        const right = expression[i + 1];
        expression.splice(i - 1, 3, left && right);
    }
}

console.log(expression);

for (let i = 0; i < expression.length; ++i) {
    if (expression[i] === '||') {
        const left = expression[i - 1];
        const right = expression[i + 1];
        expression.splice(i - 1, 3, left || right);
    }
}

console.log(expression);

You probably would want to make this code more robust and less repetitive if you were to add support for many operators, but that should get you started at least.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!