Javascript 节点js中的复杂递归
我需要帮助尝试通过这个JSON对象递归来构建查询。我是用JavaScript实现的 NodeJS 我有一个像这样的物体Javascript 节点js中的复杂递归,javascript,node.js,recursion,Javascript,Node.js,Recursion,我需要帮助尝试通过这个JSON对象递归来构建查询。我是用JavaScript实现的 NodeJS 我有一个像这样的物体 { type: "and", left: { type: "eq", left: { type: "property", name: "City" }, right: { type: "literal",
{
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传递到下面的filter方法中
我一直在尝试许多不同的食谱来达到这个目的。这与我做过的任何递归都不同
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']);
}
}
}
});
非常感谢您的帮助
当只能将属性与文字值进行比较时,不应在此处使用right
和left
(这表示任何类型的树)
如果只能表示一组子句,请使用数组。您的模型似乎不支持比这更多的功能,而且它将使您的过滤器
方法更容易(您不需要使用递归)
您似乎不打算更改格式,但当我的上述假设正确时,这就足够了:
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")
}
下面是一个答案,它采用您的树并使用递归返回结果 代码: 输出:
欢迎来到这个网站!如果你解释清楚为什么你需要帮助,你会得到更好的答案。什么不起作用?您是否收到错误消息?如果是,它们是什么?发生了什么,您期望发生什么,它们有什么不同(如果不明显的话)?什么是
类
,什么是模型
,哪些方法在哪里?如何将属性相互比较,还有其他类型吗?json的模式是什么?类只是创建原型继承和简单的基于类的语法的简单方法。阶级和模式不重要。目标是递归上面对象中的值并构建查询。is对象是根据查询字符串生成的@user3254599:好的,我发现您不能真正更改输出。但是,您想如何构建查询?我想您不是指查询字符串吧?请解释您希望代码做什么。这是一个有趣的模型。是否允许类型:'或'
?然后你要确保你正确地处理它。很好的挑战。我们差不多同时回答。我测试了您的代码(将输出更改为字符串),结果成功了。和我的基本算法一样+1它似乎无法处理lt
和gt
类型。顺便说一句,因为OP在评论中说他从解析器那里得到了语法树,我想他不想把它转换回字符串:-)lt
和gt
都是琐碎的事情。我没有可以使用的模型,所以字符串输出显示了代码需要如何编写。
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")
}
#!/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')