当前位置:  开发笔记 > 编程语言 > 正文

在目标c中将NSArray过滤为新的NSArray

如何解决《在目标c中将NSArray过滤为新的NSArray》经验,为你挑选了5个好方法。

我有一个NSArray,我想创建一个新的NSArray包含原始数组中符合特定条件的对象.标准由返回a的函数决定BOOL.

我可以创建一个NSMutableArray,遍历源数组并复制过滤器函数接受的对象,然后创建它的不可变版本.

有没有更好的办法?



1> lajos..:

NSArrayNSMutableArray提供过滤数组内容的方法.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" }


我听了Papa Smurf的播客,Papa Smurf说答案应该存在于StackOverflow中,所以社区可以对它们进行评分和改进.
@mmalc - 也许更适合,但在这里查看肯定更方便.
NSPredicate死了,万岁!比照 我的答案如下.
@ user1007522,[c]使匹配不区分大小写

2> Stuart..:

有很多方法可以做到这一点,但到目前为止最好的肯定是使用[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.
}]];

我认为这很简洁.


迅速:

对于那些NSArray在Swift中使用s的人,您可能更喜欢这个简洁的版本:

nsArray = nsArray.filter { $0.shouldIKeepYou() }

filter只是一个方法Array(NSArray隐式桥接到Swift Array).它需要一个参数:一个闭包,它接受数组中的一个对象并返回一个Bool.在闭包中,只返回true过滤数组中所需的任何对象.



3> Clay Bridges..:

如果您是OS X 10.6/iOS 4.0或更高版本,那么使用块可能比NSPredicate更好.查看-[NSArray indexesOfObjectsPassingTest:]或编写您自己的类别以添加方便-select:-filter:方法(示例).

想要别人写这个类别,测试它等等?看看BlocksKit(数组文档).这里面有很多的,比如说可以找到更多的例子,搜索如"的NSArray块类别中选择".


防止链接损坏是为了摘录链接文章中的相关代码和其他内容,而不是添加更多链接.保留链接,但添加一些示例代码.
你会介意用一个例子扩展你的答案吗?博客网站在您最需要的时候会有死亡的倾向.
@ClayBridges我发现了这个问题,寻找在可可中过滤的方法。由于您的答案中没有任何代码示例,因此我花了大约5分钟的时间来浏览您的链接,以便发现这些块无法满足我的需求。如果代码在答案中,则可能需要30秒钟。如果没有实际代码,此答案的用处不大。
mydogisbox在这一点上是正确的; 如果您所做的只是提供链接,即使您添加了更多链接,它也不是真正的答案.请参见http://meta.stackexchange.com/questions/8231.石蕊测试:*您的答案可以独立存在,还是需要点击链接才能获得任何价值?*特别是,您说"你可能比NSPredicate更好地使用块",但是你没有真的解释了原因.

4> pckill..:

根据Clay Bridges的回答,这里有一个使用块过滤的示例(更改yourArray为您的数组变量名称和testFunc测试函数的名称):

yourArray = [yourArray objectsAtIndexes:[yourArray indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
    return [self testFunc:obj];
}]];



5> Ashley Clark..:

假设您的对象都是类似的类型,您可以添加一个方法作为其基类的类别,调用您用于标准的函数.然后创建一个引用该方法的NSPredicate对象.

在某些类别中,定义使用您的函数的方法

@implementation BaseClass (SomeCategory)
- (BOOL)myMethod {
    return someComparisonFunction(self, whatever);
}
@end

那么无论你在哪里过滤:

- (NSArray *)myFilteredObjects {
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"myMethod = TRUE"];
    return [myArray filteredArrayUsingPredicate:pred];
}

当然,如果您的函数只比较类中可以访问的属性,那么将函数的条件转换为谓词字符串可能更容易.

推荐阅读
wangtao
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有