首页 > 解决方案 > Javascript从括号中拆分并使用AND / OR制作条件语句

问题描述

我想从字符串中创建条件语句,包括括号、AND 和 OR。

所以我从stackoverflow中找到了用括号分割字符串的代码。

let array = [],
  c = 0;

'(A OR B) AND C'.split(/([()])/).filter(Boolean).forEach(e =>
  e == '(' ? c++ : e == ')' ? c-- : c > 0 ? array.push('(' + e + ')') : array.push(e)
);

let finalQuery = [];
while (array.length > 0) {
  const condition = array.pop();
  // console.log(condition)
  if (condition.includes("OR")) {
    let temp = condition.trim().split(" OR ");
    temp.map(each => {
      finalQuery.push(each);
    })
  } else if (condition.includes("AND")) {
    let temp = condition.trim();
    if (temp.includes("AND")) {
      if (temp.indexOf("AND") == 0) {
        if (finalQuery.length > 0) {
          finalQuery = finalQuery.map(x => x + " " + temp.replace("AND", ""))
        }
      } else if (temp.indexOf("AND") == temp.length - 3) {
        if (finalQuery.length > 0) {
          finalQuery = finalQuery.map(x => temp.replace("AND", "") + ' ' + x)
        }
      }
    }

  }
  console.log(finalQuery)
}

我试过上面的代码。

但它不起作用。

我想要如下结果。

输入:(A OR B) AND (C OR D)

输出:A C OR A D OR B C OR B D

输入:(A OR B) AND (C OR D) AND (E OR F)

输出:A C E OR A C F OR A D E OR A D F OR B C E OR B C F OR B D E OR B D F

有人可以帮我吗?

标签: javascriptalgorithmconditional-statementswhere-clauseparentheses

解决方案


仅适用于格式A AND/OR B AND/OR C ...

让我们假设

  • A是代B也是代
  • 操作只是其中AND之一OR
  • expression = token opertaor token. - (1)

我将所有表达式评估为字符串。我有一些规则

  • A OR B-> A,B(标记为字符串)
  • A AND B->AB
  • 那么,A,B AND C可以评估为AC,BC

解析并通过括号和获取表达式()并对其进行评估。

例如,(A AND B) OR C被评估为AB OR C并再次执行AB,C。现在我们可以通过上面的(1)来评估所有表达式

这里的代码是。试试看:

function is_exp(s){
    return s.indexOf(' OR ') !== -1 || s.indexOf(' AND ') !== -1;
}

// return "exp oper exp" to evaluated exp
function eval(s) {
    // OR operation
    if (s.indexOf('OR') != -1) {
        var i = s.indexOf('OR');
        var first = s.slice(0, i - 1);
        var second = s.slice(i + 3);
        return [first, second].toString(); // merge
    }
    // AND operation
    else if (s.indexOf('AND') != -1) {
        var i = s.indexOf('AND');
        var first = s.slice(0, i - 1).split(',');
        var second = s.slice(i + 4).split(',');
        var result = [];
        for(var f0 of first) {
            for(var s0 of second) {
                result.push(f0 + s0);
            }
        }
        return result.toString();
    }
    // wrong and fail
    else {
        return "";
    }
}

function _calculate(s) {
    var l = -1, r = Infinity;
    var tokens = [];
    var opers = [];
    while (l < s.length) {
        l = s.indexOf('(', l+1);
        if (r+1 < l) {
            opers.push(s.slice(r+1, l).replace(/\s/gi, ''));
        }
        r = s.indexOf(')', l);
        if (l == -1 || r == -1) break;
        var exp = s.slice(l+1, r);
        tokens.push(is_exp(exp) ? eval(exp) : exp); // if it is expression, evaluted it.
    }

    // evaluate all chained elements
    var result = tokens[0];
    for(var i=1; i < tokens.length; ++i) {
        result = eval(result + ' ' + opers[i-1] + ' ' + tokens[i]);
    }

    // make string as good to read
    var lst = result.split(',');
    lst = lst.map((v) => (v.split('').join(' '))); // "ABC" => "A B C"
    return lst.join(' or '); // add "OR" between all tokens
}

function calculate() {
    var input = document.getElementById('input');
    var output = document.getElementById('output');
    output.value = _calculate(input.value);
}

document.addEventListener('DOMContentLoaded', calculate);
textarea { width: 100%; display: block; margin: 5px auto; }
<textarea id="input" rows="2">(A OR B) AND (C OR D)</textarea>
<button onclick="calculate()">Run</button>
<textarea id="output" rows="2" disabled readonly></textarea>

但是,在我的代码中不适用于(A AND (B OR C)) OR D.

如果您想处理上述情况的情况,我想可以通过堆栈或递归来解决,并在括号上解析得更完美。


推荐阅读