Node js中的复杂递归

时间:2014-01-30 20:43:53

标签: 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']);
      }
    }
  }
});

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

{
  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")
}

答案 1 :(得分:0)

这是一个回答,它采用树并使用递归来返回结果。

#!/usr/bin/env node
var util = require('util');
util.puts("Convert tree to query!");
var tree = { /* your tree object */ };
var readNode = function(node) {

    if (node.type === "eq") {
        return "(" + node.left.name + " = '" + node.right.value + "')";
    }
    if (node.type === "and") {
        return readNode(node.left) + " and " + readNode(node.right);
    }

};
util.puts(readNode(tree));

输出:

(City = 'Seattle') and (State = 'Washington') and (FirstName = 'John') and (LastName = 'Doe')