【发布时间】:2012-01-08 18:52:17
【问题描述】:
我尝试在我的应用程序中使用简单的比较器来过滤一些数据,并通过字符串过滤器代替功能,例如。传递给[].filter
比较器应该返回作为过滤器的函数。
var comparator = function( a, b, c ) {
switch( b ){
case '>=': return function() { return this[a] >= c;}; break;
case '<=': return function() { return this[a] <= c;}; break;
case '<': return function() { return this[a] < c;}; break;
case '>': return function() { return this[a] > c;}; break;
case '=': return function() { return this[a] == c;}; break;
case '==': return function() { return this[a] === c;}; break;
case '!=': return function() { return this[a] != c;}; break;
default: return null;
};
}
假设我通过以下方式获得此功能:
var filterFn = comparator.apply({}, /(.+)(=|>=|<=|<|>|!=|==|!==)(.+)/.exec( "id<4" ).slice(1) );
someModel = someModel.objects.filter( filterFn );
它将寻找的目标:
someModel.get = function( filter ){
return new Model(
this.objects.filter(
comparator.apply({}, /(.+)(=|>=|<=|<|>|!=|==|!==)(.+)/.exec( "id<4" ).slice(1)
)
);
};
var filtered = someModel.get( "id<4" );
问题是 - 我认为它将是更多的运算符,我不知道如何更简单地编写它。
使用 Eval 是不可能的。
这段代码没有被执行和测试,我写它只是为了说明我的意思。
【问题讨论】:
-
即使您将运算符
c与一组已知的、列入白名单的可能值进行比较,eval()是否也不可能? -
你是否需要一个完整的表达式解析器,例如不只有单一的运营商?
-
请注意,您不需要在每个
return之后使用break语句。 -
@nnnnnn 我知道。我必须重写表达式中的运算符以及附加的开关列表,这让我很恼火。虽然可能无法做到这一点。
-
@Michael 的提示令人深思……