我需要帮助尝试递归此 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" } }
当您只能将属性与文字值进行比较时,不应在此处使用 right
和 left
(这表明任何类型的树)。
{ 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/