Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

175
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda