如何在数组中存储多级条件并实现复杂条件处理函数
如何在数组中存储多级条件并实现复杂条件处理函数
嘿,这个需求我之前做类似业务逻辑时也碰到过!你已经搞定了简单条件的判断,要扩展到嵌套的复杂条件,核心思路就是递归处理——毕竟你的条件结构本身就是递归的:复杂条件里可以嵌套简单条件,也可以嵌套另一个复杂条件。咱们一步步来实现:
1. 先明确条件结构规则
先把你的条件格式理清楚,方便后续代码逻辑对齐:
- 简单条件:固定长度为3的数组,格式为
[字段名, 比较操作符, 目标值],比如["name", "==", "John Doe"] - 复杂条件:长度为奇数的数组(结构是
[条件1, 组合操作符, 条件2, 组合操作符, 条件3...]),其中每个“条件”既可以是简单条件,也可以是另一个复杂条件;组合操作符包括AND、OR、AND NOT这类
2. 优化现有简单条件处理函数
我先把你原有的简单条件函数做了点小优化,比如变量命名更清晰,加上了类型转换的小处理(避免字符串数字比较的坑),还有容错处理:
function getResultOfSimpleCondition(data, condition) { const [field, operator, value] = condition; const fieldValue = data[field]; let result = true; switch(operator) { case "==": case "=": result = fieldValue == value; break; case "!=": result = fieldValue != value; break; case ">": // 尝试转数字比较,避免"28">"100"这种字符串比较的错误 result = Number(fieldValue) > Number(value); break; case "<": result = Number(fieldValue) < Number(value); break; case ">=": result = Number(fieldValue) >= Number(value); break; case "<=": result = Number(fieldValue) <= Number(value); break; case "like": // 确保转字符串再调用indexOf,避免非字符串类型报错 result = String(fieldValue).indexOf(value) > -1; break; case "not like": result = String(fieldValue).indexOf(value) === -1; break; default: console.warn(`未知比较操作符:${operator},默认使用==判断`); result = fieldValue == value; break; } return result; }
3. 实现复杂条件处理函数(核心:递归)
复杂条件的关键就是递归判断每个元素:如果是数组,就递归处理这个子条件;如果是组合操作符,就用它来组合前后的判断结果。同时加上短路优化,能提升一点性能:
function getResultOfComplexCondition(data, condition) { // 先判断当前是不是简单条件,是就直接调用已有函数 if (Array.isArray(condition) && condition.length === 3) { return getResultOfSimpleCondition(data, condition); } // 初始化结果为第一个子条件的判断结果 let currentResult = getResultOfComplexCondition(data, condition[0]); // 从索引1开始,每次取操作符+下一个条件(步长为2) for (let i = 1; i < condition.length; i += 2) { const operator = condition[i]; const nextCondition = condition[i + 1]; const nextResult = getResultOfComplexCondition(data, nextCondition); // 根据组合操作符更新当前结果 switch(operator) { case "AND": currentResult = currentResult && nextResult; // 短路优化:已经是false了,后面的AND判断不用做了 if (!currentResult) break; break; case "OR": currentResult = currentResult || nextResult; // 短路优化:已经是true了,后面的OR判断不用做了 if (currentResult) break; break; case "AND NOT": currentResult = currentResult && !nextResult; break; default: console.warn(`未知组合操作符:${operator},默认按AND处理`); currentResult = currentResult && nextResult; break; } } return currentResult; }
4. 测试你的示例场景
咱们用你给出的例子来验证一下,顺便补全你提到的condition_5和condition_23:
const myData = { name:'John Doe', age:'28', town:'PARIS', qty:5, uptodate: true}; // 定义所有测试条件 const condition_0 = ["name", "==", "Jack Sparrow"]; // false const condition_1 = ["age", ">=", "24"]; // true const condition_2 = ["uptodate", "==", false]; // false const condition_3 = ["town", "==", "PARIS"]; // true const condition_5 = ["qty", ">", 3]; // true const condition_23 = ["uptodate", "==", true]; // true // 测试二级条件 console.log(getResultOfComplexCondition(myData, [condition_0, "OR", condition_1])); // 输出:true console.log(getResultOfComplexCondition(myData, [condition_1, "AND", condition_2])); // 输出:false // 测试多级嵌套条件 console.log(getResultOfComplexCondition(myData, [[condition_0, "OR", condition_1], "AND", condition_3])); // 输出:true console.log(getResultOfComplexCondition(myData, [[condition_0, "OR", condition_1], "AND", condition_3, "AND NOT", [condition_5, "OR", condition_23]])); // 输出:false
可以扩展的小功能
如果后续需要更强大的能力,还能加这些功能:
- 操作符优先级:比如让
AND比OR优先级更高,这需要先把条件拆分成OR分组,每组内处理AND逻辑 - 更多操作符:比如支持
starts with、ends with,或者针对数组的in操作(比如["role", "in", ["admin", "editor"]]) - 严格类型检查:比如判断简单条件时,除了长度3,还要验证第二个元素是合法的比较操作符
备注:内容来源于stack exchange,提问作者Lionel KAISER
相关产品推荐
相关产品推荐

