laj*_*jos 117 cocoa objective-c nsarray
我有一个NSArray,我想创建一个新的NSArray包含原始数组中符合特定条件的对象.标准由返回a的函数决定BOOL.
我可以创建一个NSMutableArray,遍历源数组并复制过滤器函数接受的对象,然后创建它的不可变版本.
有没有更好的办法?
laj*_*jos 137
NSArray并NSMutableArray提供过滤数组内容的方法.NSArray提供filteredArrayUsingPredicate:它返回一个新数组,其中包含接收器中与指定谓词匹配的对象.NSMutableArray添加filterUsingPredicate:它根据指定的谓词计算接收者的内容,只留下匹配的对象.以下示例说明了这些方法.
NSMutableArray *array =
[NSMutableArray arrayWithObjects:@"Bill", @"Ben", @"Chris", @"Melissa", nil];
NSPredicate *bPredicate =
[NSPredicate predicateWithFormat:@"SELF beginswith[c] 'b'"];
NSArray *beginWithB =
[array filteredArrayUsingPredicate:bPredicate];
// beginWithB contains { @"Bill", @"Ben" }.
NSPredicate *sPredicate =
[NSPredicate predicateWithFormat:@"SELF contains[c] 's'"];
[array filteredArrayUsingPredicate:sPredicate];
// array now contains { @"Chris", @"Melissa" }
Run Code Online (Sandbox Code Playgroud)
Stu*_*art 100
有很多方法可以做到这一点,但到目前为止最好的肯定是使用[NSPredicate predicateWithBlock:]:
NSArray *filteredArray = [array filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id object, NSDictionary *bindings) {
return [object shouldIKeepYou]; // Return YES for each object you want in filteredArray.
}]];
Run Code Online (Sandbox Code Playgroud)
我认为这很简洁.
对于那些NSArray在Swift中使用s的人,您可能更喜欢这个更简洁的版本:
nsArray = nsArray.filter { $0.shouldIKeepYou() }
Run Code Online (Sandbox Code Playgroud)
filter只是一个方法Array(NSArray隐式桥接到Swift Array).它需要一个参数:一个闭包,它接受数组中的一个对象并返回一个Bool.在闭包中,只返回true过滤数组中所需的任何对象.
Cla*_*ges 47
如果您是OS X 10.6/iOS 4.0或更高版本,那么使用块可能比NSPredicate更好.查看-[NSArray indexesOfObjectsPassingTest:]或编写您自己的类别以添加方便-select:或-filter:方法(示例).
想要别人写这个类别,测试它等等?看看BlocksKit(数组文档).这里面有很多的,比如说可以找到更多的例子,搜索如"的NSArray块类别中选择".
pck*_*ill 45
根据Clay Bridges的回答,这里有一个使用块过滤的示例(更改yourArray为您的数组变量名称和testFunc测试函数的名称):
yourArray = [yourArray objectsAtIndexes:[yourArray indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
return [self testFunc:obj];
}]];
Run Code Online (Sandbox Code Playgroud)
Ash*_*ark 16
假设您的对象都是类似的类型,您可以添加一个方法作为其基类的类别,调用您用于标准的函数.然后创建一个引用该方法的NSPredicate对象.
在某些类别中,定义使用您的函数的方法
@implementation BaseClass (SomeCategory)
- (BOOL)myMethod {
return someComparisonFunction(self, whatever);
}
@end
Run Code Online (Sandbox Code Playgroud)
那么无论你在哪里过滤:
- (NSArray *)myFilteredObjects {
NSPredicate *pred = [NSPredicate predicateWithFormat:@"myMethod = TRUE"];
return [myArray filteredArrayUsingPredicate:pred];
}
Run Code Online (Sandbox Code Playgroud)
当然,如果您的函数只比较类中可以访问的属性,那么将函数的条件转换为谓词字符串可能更容易.