Evaluate simple condition programmatically in javascript

Viewed 56

I have a list of simple objects:

const conditions = [
    {value: true, op: "AND"},
    {value: true, op: "AND"},
    {value: false, op: "OR"},
    {value: true, op: null},
]

How can I effectively reduce and resolve this condition so I end up with a "true"?

Ive tried iterating stupidly over them and creating new lists that then get processed again and got quite close, but I wasn't able to get it to work this way and there most likely is a much more efficient way with just one loop or with recursive function calls, but I just cant get it to work right now...

Grateful for any input

Edit: I was able to get to a solution that seems to work. However, it is not very efficient since it always processes all list entries when it could early exit because of boolean logic:

const check = (results) => {
    return results.reduce((prev, cur) => {
        if (prev.op === "AND") {
            return {value: prev.value && cur.value, op: cur.op};
        }
        return {value: prev.value || cur.value, op: cur.op};
    }).value;
}

Still interested in more efficient approaches

Edit 2: I found a case where this reduce method won't work. I resorted to using simple loops. Using strings as inputs makes the evaluation a lot easier:

const checkWithLoops = (test) => {
  const andPairs = test.split("or");

  const andResults = [];

  for (let i = 0; i < andPairs.length; i++) {
    const vals = andPairs[i].split(" ");
    let andRes = true;
    for (let o = 0; o < vals.length; o++) {
      if (vals[o] === "false") {
        andRes = false;
      }
    }
    andResults.push(andRes);
  }

  let orResult = false;
  for (let i = 0; i < andResults.length; i++) {
    if (andResults[i] === true) {
      orResult = true;
      break;
    }
  }

  return orResult;
};
1 Answers

The current form of conditions is a bit odd and there's a good chance you could could benefit from improving your program before this point. And reduce is not a good fit because it will iterate thru the entire conditions array even when a solution can be determined earlier. However, one solution for the current form is to write a simple recursive eval -

function eval(t = []) {
  if (t.length == 0)
    return undefined
  else switch (t[0].op) {
    case "AND":
      return t[0].value && eval(t.slice(1))
    case "OR":
      return t[0].value || eval(t.slice(1))
    default:
      return t[0].value
  }
}

const conditions = [
    {value: true, op: "AND"},
    {value: true, op: "AND"},
    {value: false, op: "OR"},
    {value: true, op: null},
]

console.log(eval(conditions))
// true && (true && (false || true))
// true && (true && true)
// true && true
// true

Related