NSExpression
来源:互联网 发布:js屏蔽查看网页源代码 编辑:程序博客网 时间:2024/05/28 01:34
本文转自:NSHipster中文博客
每当涉及查询或者整理信息时,Cocoa总是其他标准库羡慕的对象。通过使用NSPredicate
,NSSortDescriptor
,以及偶尔使用NSFetchRequest
,即使是最复杂的数据任务也可以被简化成为几行极其容易读懂的代码。
现在,NSHipster们无疑已经熟悉NSPredicate
了(如果你还不熟悉,下周一定要过来看看),不过如果我们更进一步看看NSPredicate
,我们会发现NSPredicate
其实是由更小的部分而组成:两个NSExpression
(一个左手值和一个右手值),和一个运算符相比较(比如<
,IN
,LIKE
等等)。
大多数开发者通过+predicateWithFormat:
来使用NSPredicate
,NSExpression
是一个相对难懂的类。真可惜啊,因为NSExpression
本身的功能非常强大。
所以,亲爱的读者,请允许我来表达我对NSExpression
深深的尊重和着迷:
评估数学
关于NSExpression
你所要知道的第一件事就是它的主要目的是减少表达。如果你思考一下评估NSPredicate
的过程,你会发现它有两个表达和一个比较符号,所以我们需要将两个表达简化为运算符可以处理的表达--非常像编译一行代码的过程。
这就是我们要学习的NSExpression
的第一招: 做数学题。
NSExpression *expression = [NSExpression expressionWithFormat:@"4 + 5 - 2**3"];id value = [expression expressionValueWithObject:nil context:nil]; // => 1
这并不是Wolfram Alpha,但是如果加入评估数学表达式对于你的应用很有用的话,那么...你就可以使用NSExpression。
函数
我们仅仅触及了NSExpression
的表面。觉得一台电脑仅仅做小学数学不怎么厉害?那高中的统计学怎么样?
NSArray *numbers = @[@1, @2, @3, @4, @4, @5, @9, @11];NSExpression *expression = [NSExpression expressionForFunction:@"stddev:" arguments:@[[NSExpression expressionForConstantValue:numbers]]];id value = [expression expressionValueWithObject:nil context:nil]; // => 3.21859...
NSExpression
函数以给定数目的子表达式作为参数。比如,在上述例子中,要得到集合的标准差,数列中的数字要被+expressionForConstantValue:
封装。虽然只是一个小小的不便(它最终却能使得NSExpression
变得极其灵活),却足以使第一次尝试它的人绊倒。
如果你觉得 键值编码简单集合运算符 (@avg
,@sum
等等)不够用,也许NSExpression
的自带的统计,算术和位运算功能能激起你的兴趣。
要注意的是:根据Apple的
NSExpression
文档中的表格,很明显,Mac OS X & iOS的功能可用性之间没有重叠。看起来最近的iOS版本的确支持如stddev
之类的函数,但这些变化并没有显示在头文件或者文档里。如果你注意到任何变化,请以pull request的形式告诉我,不胜感激。
统计
average:
sum:
count:
min:
max:
median:
mode:
stddev:
基本运算
这些函数需要用两个NSExpression
对象来表达数字。
add:to:
from:subtract:
multiply:by:
divide:by:
modulus:by:
abs:
高级运算
sqrt:
log:
ln:
raise:toPower:
exp:
边界函数
ceiling:
- (不小于数组中的值的最小积分值)trunc:
- (最接近但不大于数组中的值的积分值)
与math.h
函数类似的函数
ceiling
非常容易和ceil(3)
混淆。ceiling
作用于数字数组,而ceil(3)
作用于一个double
值(且它并没对应的内置NSExpression
函数)。floor:
在这里的作用和floor(3)
一样。
floor:
随即函数
两个变量--一个带参数,一个不带参数。不带参数时,random
返回rand(3)
的等值,而random:
则从NSExpression
的数字数组中取任意元素。
random
random:
二进制运算
bitwiseAnd:with:
bitwiseOr:with:
bitwiseXor:with:
leftshift:by:
rightshift:by:
onesComplement:
日期函数
now
字符串函数
lowercase:
uppercase:
空操作
noindex:
自定义函数
除了这些内置的函数,你也可以在NSExpression
中调用自定义函数。由Dave DeLong所撰写的这篇文章 详述了这个过程。
首先,在类别中定义一个对应的函数:
@interface NSNumber (Factorial)- (NSNumber *)factorial;@end@implementation NSNumber (Factorial)- (NSNumber *)factorial { return @(tgamma([self doubleValue] + 1));}@end
然后,这样使用函数(+expressionWithFormat:
中的FUNCTION()
宏是构造-expressionForFunction:
等等的过程的简写。):
NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(4.2, 'factorial')"];id value = [expression expressionValueWithObject:nil context:nil]; // 32.578...
这样的优势在于, 通过直接调用-factorial
,我们可以调用NSPredicate
查询中的函数。比如,我们可以定义一个location:withinRadius:
方法来轻松的查询用户当前位置附近的管理对象。
正如Dave在他的文章中所提到的那样,这些用例十分边缘化,但它们肯定可以成为你的保留节目中有趣的技巧。.
- NSExpression
- NSExpression
- NSExpression
- NSExpression
- NSExpression
- NSExpression
- 【Cocoa】NSExpression
- NSExpression转自CocoChina
- iOS NSExpression介绍
- IOS 之 NSExpression 条件表达式
- file类renameTo使用小demo
- codeforces C. Team
- VC6.0使用教程-30分钟玩转Microsoft Visual C++ 6.0
- 华为机试题--数列求和
- Codeforces Round #235 (Div. 2)B. Sereja and Contests
- NSExpression
- codeforces A. Vanya and Cards
- 华为机试题---四舍五入
- 十款PHP开发者编码工具 你用过哪些?
- javac,使用"-d ."与省略-d的区别
- codeforces_235_div2解题报告
- 删除一个字符串里出现次数最多(少)的子字符串
- codeforces B. Sereja and Contests
- 资源管理器收藏夹项目不能再当前窗口打开的解决方法