javascript - Node js 中的复杂递归

标签 javascript node.js recursion

我需要帮助尝试递归此 JSON 对象来构建查询。我在 JavaScript 中这样做。

NodeJS

我有一个看起来像这样的对象

    {
      type: "and",
      left: {
        type: "eq",
        left: {
          type: "property",
          name: "City"
        },
        right: {
          type: "literal",
          value: "Seattle"
        }
      },
      right: {
        type: "and",
        left: {
          type: "eq",
          left: {
            type: "property",
            name: "State"
          },
          right: {
            type: "literal",
            value: "Washington"
          }
        },
        right: {
          type: "and",
          left: {
            type: "eq",
            left: {
              type: "property",
              name: "FirstName"
            },
            right: {
              type: "literal",
              value: "John"
            }
          },
          right: {
            type: "eq",
            left: {
              type: "property",
              name: "LastName"
            },
            right: {
              type: "literal",
              value: "Doe"
            }
          }
        }
      }
    };

这是一些代码。上面的对象将作为 querySchema 传递到下面的过滤器方法中。

我一直在尝试许多不同的食谱来完成这个任务。这与我做过的任何递归都不同。

var QueryBuilder = Class({
  constructor: function (model) {
  this.model = new model();
  },

  filter: function (querySchema) {
    var self = this;

    // recurse somewhere in here and run the conditions below somewhere in the midst
    // of the recursion.

    if (querySchema.hasOwnProperty(property)) {

      if (property == 'type' && querySchema[property] == 'and') {
        self.filter(querySchema.left);
      }


      if (querySchema.type == 'eq') {
        this.model.where(querySchema.left.name).equals(querySchema.right.);
      }

      if (querySchema.type == 'gt') {
        this.model.where(querySchema.left.name).gt(querySchema['right']);
      }
      if (querySchema.type == 'lt') {
        this.model.where(querySchema.left.name).lt(querySchema['right']);
      }
    }
  }
});

非常感谢任何帮助。

最佳答案

{
  type: "eq",
  left: {
    type: "property",
    name: "State"
  },
  right: {
    type: "literal",
    value: "Washington"
  }
}

当您只能将属性与文字值进行比较时,不应在此处使用 rightleft(这表明任何类型的树)。

{
  type: "and",
  left: …,
  right: {
    type: "and",
    left: …,
    right: {
      type: "and",
      left: …,
      right: …
    }
  }
};

如果只能表示conjunction,请使用数组的条款。您的模型似乎并不支持比这更多的功能,并且它将使您的 filter 方法变得更加容易(您不需要使用递归)。

您似乎不打算更改格式,但是当我的上述假设正确时,那么这应该足够了:

filter: function (querySchema) {
  if (querySchema.type == 'and') {
    // standard binary tree traversal recursion:
    this.filter(querySchema.left);
    this.filter(querySchema.right);
  } else if (querySchema.type == 'eq') {
    this.model.where(querySchema.left.name).equals(querySchema.right.value);
  } else if (querySchema.type == 'gt') {
    this.model.where(querySchema.left.name).gt(querySchema.right.value);
  } else if (querySchema.type == 'lt') {
    this.model.where(querySchema.left.name).lt(querySchema.right.value);
  }
}

一个更强大的版本(但不改变递归)将是:

filter: function (querySchema) {
  var t = querySchema.type, l = querySchema.left, r = querySchema.right;
  if (t == 'and') {
    this.filter(l);
    this.filter(r);
  } else if (t == 'eq' || t == 'gt' || == 'lt') {
      if (l.type != "property" || r.type != "literal")
        throw new SyntaxError("Invalid comparison in query schema");
      this.model.where(l.name)[t=='eq'?'equals':t](r.value);
  } else
    throw new SyntaxError("Unknown type in query schema")
}

关于javascript - Node js 中的复杂递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21467039/

相关文章:

javascript - 提交表单时显示 ajax 加载程序图标

javascript - 在 Ubuntu 18.04 上使用 Sequelize 时出现接收错误。在 Mac 上使用完全相同的文件不会发生错误

c# - 使用响应式(Reactive)扩展在逻辑门模拟器中创建稳定的反馈回路?

algorithm - 在二叉树中找到最大的不相交叶到叶路径之和

javascript - 如果存在新记录,则启用编辑按钮

javascript - AJAX Rails - 请求明显丢失 - 没有 UI 结果

node.js - 程序 'node.exe' 无法在 Visual Studio Code 中运行

javascript - 递归对象数组以创建自定义类对象

Javascript参数改变值?

Node.js 中的 Json 到 csv