NSNumber *transactionAverage = [self.transactions valueForKeyPath:@"@avg.amount"];
当你发送符合键值的对象valueForKeyPath:
消息时,可以在key path中嵌入一个集合运算符。 一个集合运算符是一个小的关键字列表之一,前面有一个符号(@),它指定了getter在返回之前以某种方式对数据进行处理。NSObject提供的valueForKeyPath
默认实现实现了这种行为。
当 key path包含了集合运算符时,运算符之前的 key path的部分(称为左键路径)指明了该消息的接收方的集合。 如果将消息直接发送到集合对象(例如NSArray
实例),则可以省略左侧的key path(如上方的例子)。
运算符之后的部分(称为右键路径)指定运算符符应该在集合内操作的属性。 除了@count以外的所有集合运算符都需要一个正确的键路径。
集合运算有三种类型的运算:
有一个简单实例
@interface Transaction : NSObject
@property (nonatomic) NSString* payee; // To whom
@property (nonatomic) NSNumber* amount; // How much
@property (nonatomic) NSDate* date; // When
@end
有一个数组self.transactions包含了一些对象的数据
payee values | amount values formatted as currency | date values formatted as month day, year |
---|---|---|
Green Power | $120.00 | Dec 1, 2015 |
Green Power | $150.00 | Jan 1, 2016 |
Green Power | $170.00 | Feb 1, 2016 |
Car Loan | $250.00 | Jan 15, 2016 |
Car Loan | $250.00 | Feb 15, 2016 |
Car Loan | $250.00 | Mar 15, 2016 |
General Cable | $120.00 | Dec 1, 2015 |
General Cable | $155.00 | Jan 1, 2016 |
General Cable | $120.00 | Feb 1, 2016 |
Mortgage | $1,250.00 | Jan 15, 2016 |
Mortgage | $1,250.00 | Feb 15, 2016 |
Mortgage | $1,250.00 | Mar 15, 2016 |
Animal Hospital | $600.00 | Jul 15, 2016 |
NSNumber *transactionAverage = [self.transactions valueForKeyPath:@"@avg.amount"];
这个可以求得amount
属性的平均值
NSNumber *numberOfTransactions = [self.transactions valueForKeyPath:@"@count"];
可以求得集合里对象的总数量
NSDate *latestDate = [self.transactions valueForKeyPath:@"@max.date"];
可以得到date
这个属性的最大值
NSDate *earliestDate = [self.transactions valueForKeyPath:@"@min.date"];
可以得到date
这个属性的最小值
NSNumber *amountSum = [self.transactions valueForKeyPath:@"@sum.amount"];
可以得到amount
这个属性的总和
The array operators cause
valueForKeyPath:
to return an array of objects corresponding to a particular set of the objects indicated by the right key path.
会根据键值路径返回一个对应的数组
NSArray *distinctPayees = [self.transactions valueForKeyPath:@"@distinctUnionOfObjects.payee"];
会得到payee这个属性的的值,里面的值会去重
NSArray *payees = [self.transactions valueForKeyPath:@"@unionOfObjects.payee"];
会得到payee这个属性的的值,与上面那个不一样,里面的值不会去重
The nesting operators operate on nested collections, where each entry of the collection itself contains a collection.
嵌套运算操作在嵌套集合(一个集合里包含了另外的集合)
The
valueForKeyPath:
method raises an exception if any of the leaf objects isnil
when using nesting operators.
有任何子对象为空,会出错。
我们增加一个数组进行嵌套
NSArray* moreTransactions = @[<# transaction data #>];
NSArray* arrayOfArrays = @[self.transactions, moreTransactions];
NSArray *collectedDistinctPayees = [arrayOfArrays valueForKeyPath:@"@distinctUnionOfArrays.payee"];
会返回两个数组里payee属性不同的值,与 @unionOfArrays
类似,但是不会去重。
NSArray *collectedPayees = [arrayOfArrays valueForKeyPath:@"@unionOfArrays.payee"];
返回两个数组里payee属性所有的值,且不去重