You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编译并评估含嵌套逻辑运算符的类MongoDB风格对象?

Custom Logical Expression Evaluator (MongoDB-style $and/$or)

Absolutely! You can build a lightweight custom evaluator that handles nested $and/$or operators, maps identifiers like foo/bar/baz to your evaluation functions, and even supports inline functions. Let's put this together step by step.

Step 1: Keep Your Evaluation Functions

First, retain your existing evaluation logic as-is:

export const evalFoo = items => items.indexOf("foo") >= 0;
export const evalBar = items => items.indexOf("bar") >= 0;
export const evalBaz = items => items.indexOf("baz") >= 0;

Step 2: Build the Core Evaluator

This recursive function will traverse your expression structure, resolve each component, and apply the logical operations:

// Map identifiers to their corresponding evaluation functions
const evalMap = {
  foo: evalFoo,
  bar: evalBar,
  baz: evalBaz
};

export const evaluateExpression = (expr) => {
  // Case 1: Execute inline functions directly (like () => m < n)
  if (typeof expr === 'function') {
    return expr();
  }

  // Case 2: Handle logical operators ($and/$or)
  if (typeof expr === 'object' && expr !== null) {
    // $and requires all sub-expressions to be true (short-circuits on first false)
    if ('$and' in expr) {
      return expr.$and.every(subExpr => evaluateExpression(subExpr));
    }
    // $or requires at least one sub-expression to be true (short-circuits on first true)
    if ('$or' in expr) {
      return expr.$or.some(subExpr => evaluateExpression(subExpr));
    }
    // Case 3: Match identifiers (foo/bar/baz) to their eval functions
    for (const [key, value] of Object.entries(expr)) {
      if (evalMap[key]) {
        return evalMap[key](value);
      }
    }
  }

  // Fallback for unrecognized structures
  return false;
};

Step 3: Validate with Your Test Cases

Let's test this evaluator against all your scenarios. Each test wraps variables like m/n to scope them properly:

Test Set 1

const testSet1 = () => {
  const m = 4; const n = 1;
  const expr = { 
    $or: [ 
      { $and: [ { foo: ['foo', 'x'] }, { bar: ['bar', 'y'] } ] }, 
      { baz: ['baz', 'z'] }, 
      () => m < n 
    ] 
  };
  return evaluateExpression(expr); // Expected: true
};
console.log(testSet1()); // Output: true

Why? The $and clause passes (both evalFoo and evalBar return true), so the $or short-circuits to true immediately.

Test Set 2

const testSet2 = () => {
  const m = 4; const n = 1;
  const expr = { 
    $or: [ 
      { $and: [ { foo: ['x'] }, { bar: ['y'] } ] }, 
      { baz: ['x'] }, 
      () => m < n 
    ] 
  };
  return evaluateExpression(expr); // Expected: false
};
console.log(testSet2()); // Output: false

Why? All options fail: the $and clause returns false, evalBaz returns false, and m < n is false.

Test Set 3

const testSet3 = () => {
  const m = 1; const n = 3;
  const expr = { 
    $or: [ 
      { $and: [ { foo: ['x'] }, { bar: ['y'] } ] }, 
      { baz: ['x'] }, 
      () => m < n 
    ] 
  };
  return evaluateExpression(expr); // Expected: true
};
console.log(testSet3()); // Output: true

Why? The inline function () => m < n returns true, so the $or evaluates to true.

Test Set 4

const testSet4 = () => {
  const m = 3; const n = 1;
  const expr = { 
    $or: [ 
      { $and: [ { foo: ['x'] }, { bar: ['bar'] } ] }, 
      { baz: ['z'] }, 
      () => m > n // Corrected to match test description's "m > n" logic
    ] 
  };
  return evaluateExpression(expr); // Expected: true
};
console.log(testSet4()); // Output: true

Why? The inline function () => m > n returns true, so the $or evaluates to true.

Key Features Breakdown

  • Recursive Nested Support: The evaluator drills down into any depth of $and/$or arrays, so you can build complex expressions without limits.
  • Extensible Mapping: Add new identifier-to-function mappings to evalMap anytime to support more evaluation logic.
  • Efficient Short-Circuiting: Uses every() for $and and some() for $or to stop evaluating as soon as the result is determined, saving unnecessary computations.
  • Flexible Inline Functions: Pass custom logic directly into the expression for one-off conditions that don't fit the identifier pattern.

内容的提问来源于stack exchange,提问作者Mutai Mwiti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:38:10