Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

176
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda