是的,您可以这样做。这属于“将NSPredicate 用于非预期用途”的类别,但可以正常工作。
您需要用一个以$ 开头的单词替换变量,因为NSPredicate 就是这样表示变量的:
NSPredicate *p = [NSPredicate predicateWithFormat:@"foo = $bar"];
不管你想这样做,太好了。 NSRegularExpression 是一个很好的方法。
一旦你这样做了,你就会有这样的东西:
@"$profitability2011 = $profit2011 / $revenue2011"
然后您可以通过+predicateWithFormat: 弹出此消息。您将收到NSComparisonPredicate。 -leftExpression 的类型为 NSVariableExpressionType,-rightExpression 的类型为 NSFunctionExpressionType。
这就是事情开始变得棘手的地方。如果您要使用-evaluteWithObject:substitutionVariables:,您只需返回YES 或NO 值,因为predicate is simply a statement that evaluates to true or false。我还没有探讨过如何只评估一侧(在本例中为-rightExpression),但-[NSExpression expressionValueWithObject:context:] 可能会对您有所帮助。我不知道,因为我不确定“上下文”参数的用途。它似乎不像是替代字典,但我可能错了。
因此,如果这不起作用(我不知道它是否会起作用),您可以使用我的解析器:DDMathParser。它有一个解析器,类似于NSPredicate 的解析器,但专门针对解析和评估数学表达式进行了调整。在你的情况下,你会这样做:
#import "DDMathParser.h"
NSString *s = @"$profit2011 / $revenue2011";
NSDictionary *values = ...; // the values of the variables
NSNumber *profitability = [s numberByEvaluatingStringWithSubstitutions:values];
DDMathParseris quite extensive 的文档,它可以做很多事情。
编辑动态变量分辨率
我刚刚推送了一个允许 DDMathParser 动态解析函数的更改。了解函数与变量不同是很重要的。评估一个函数,而简单地替换一个变量。但是,此更改仅对 函数 进行动态解析,而不是变量。没关系,因为 DDMathParser 有一个叫做 argumentless functions 的简洁的东西。
无参数函数是一个函数名,后面没有左括号。为方便起见,它已为您插入。这意味着@"pi" 被正确解析为@"pi()"(因为 π 的常量是作为函数实现的)。
在你的情况下,你可以这样做:
不用正则表达式来生成变量,只需使用术语的名称:
@"profit_2011 / revenue_2011";
这将被解析为就像您输入了:
@"divide(profit_2011(), revenue_2011())"
您可以使用函数解析器设置您的DDMathEvaluator 对象。在DDMathParser 存储库中有两个这样的例子:
-
This example 展示了如何使用解析器函数在替换字典中查找“缺失”函数(这将最符合您的要求)
-
This example 向您展示如何解释任何缺失的函数,就好像它评估为 42。
一旦实现了解析器函数,您就可以不必将所有变量打包到字典中。