数组的排序及筛选
sortedArrayUsingComparator
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
NSArray *array = @[@"4",@"2",@"3",@"1",@"3"]; NSLog(@"排序前: %@",array); NSComparator comparator = ^(id obj1, id obj2){ if([obj1 integerValue] > [obj2 integerValue]) { return NSOrderedDescending; } if([obj1 integerValue] < [obj2 integerValue]) { return NSOrderedAscending; } return NSOrderedSame; //return (arc4random() % 3) - 1; //随机排序 }; array = [array sortedArrayUsingComparator:comparator]; NSLog(@"排序后: %@",array);
sortedArrayUsingFunction:customSort
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
- (void)viewDidLoad { [super viewDidLoad]; NSArray *array = @[@"4",@"2",@"3",@"1",@"3"]; NSLog(@"排序前: %@",array); array = [array sortedArrayUsingFunction:customSort context:nil]; NSLog(@"排序后: %@",array); } NSInteger customSort(id obj1, id obj2, void* context) { if ([obj1 integerValue] > [obj2 integerValue]) { return NSOrderedDescending; } if ([obj1 integerValue] < [obj2 integerValue]) { return NSOrderedAscending; } return NSOrderedSame; }
sortUsingDescriptors
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#import <Foundation/Foundation.h> @interface TopMenuItem : NSObject @property (strong, nonatomic) NSString *title; @property (assign, nonatomic) NSInteger order; @property (assign, nonatomic) BOOL selected; @end #import "TopMenuItem.h" @implementation TopMenuItem - (NSString *)description { return [NSString stringWithFormat:@"title:%@, order:%d, selected:%d",self.title,self.order,self.selected]; } @end - (void)viewDidLoad { [super viewDidLoad]; NSMutableArray *channelArray = [NSMutableArray array]; TopMenuItem *item = [[TopMenuItem alloc] init]; item.title = @"要闻"; item.order = 1; item.selected = YES; [channelArray addObject:item]; item = [[TopMenuItem alloc] init]; item.title = @"半导体照明"; item.selected = YES; item.order = 3; [channelArray addObject:item]; item = [[TopMenuItem alloc] init]; item.title = @"电子工程"; item.selected = YES; item.order = 2; [channelArray addObject:item]; item = [[TopMenuItem alloc] init]; item.title = @"光通讯"; item.selected = NO; item.order = 3; [channelArray addObject:item]; NSLog(@"排序前"); for (TopMenuItem *item in channelArray) { NSLog(@"%@",item); } NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"order" ascending:YES]; NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc] initWithKey:@"selected" ascending:YES]; [channelArray sortUsingDescriptors:[NSArray arrayWithObjects:sortDescriptor1, sortDescriptor2, nil]]; NSLog(@"排序后"); for (TopMenuItem *item in channelArray) { NSLog(@"%@",item); } }
makeObjectsPerformSelector
这个方法可以让数组内的所有元素都执行同一个对象方法,在特定场合可以替代for循环使用。
还是沿用上面例子里的TopMenuItem类,新加入一个方法:
- (void)testFun:(NSString *)str { NSLog(@"testFun,param is:%@,title is %@",str,self.title); }
然后就可以这样调用:
[channelArray makeObjectsPerformSelector:@selector(testFun:) withObject:@"测试"];
NSPredicate
Cocoa框架中的NSPredicate主要用于查询并过滤元素,比较类似于Sql语句中的where,使用方法如下:
NSArray *array = @[@"A",@"AB",@"ABC",@"D",@"DF"]; NSLog(@"排序前: %@",array); NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF Contains 'A'"]; NSArray *newArray = [array filteredArrayUsingPredicate:predicate]; NSLog(@"排序后: %@",newArray);
如果是NSMutableArray,则可以直接调用filterUsingPredicate来过滤原数组。
比较运算符
> >= < <= == !=(或<>)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
NSMutableArray *array = [NSMutableArray arrayWithArray:@[[NSNumber numberWithInt:1], [NSNumber numberWithInt:4], [NSNumber numberWithInt:23], [NSNumber numberWithInt:999], [NSNumber numberWithInt:83],]]; NSLog(@"原数组: %@",array); NSString *filterString = @"SELF>50"; //get 83,999 filterString = @"SELF==23"; //get 23 filterString = @"SELF<=23"; //get 1,4,23 NSPredicate *predicate = [NSPredicate predicateWithFormat:filterString]; [array filterUsingPredicate:predicate]; NSLog(@"过滤后: %@",array);
范围运算符
IN BETWEEN
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
NSMutableArray *array = [NSMutableArray arrayWithArray:@[[NSNumber numberWithInt:1], [NSNumber numberWithInt:4], [NSNumber numberWithInt:23], [NSNumber numberWithInt:999], [NSNumber numberWithInt:83],]]; NSLog(@"原数组: %@",array); NSString *filterString = @"SELF BETWEEN {4,50}"; //get 4,23 filterString = @"SELF IN {23,999}"; //get 23,999 NSPredicate *predicate = [NSPredicate predicateWithFormat:filterString]; [array filterUsingPredicate:predicate]; NSLog(@"过滤后: %@",array);
字符串比较
LIKE BEGINWITH CONTAINS ENDSWITH MATCHES
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
NSArray *array = @[@"park",@"army",@"phone",@"warrior",@"stone",@"ear",@"apple",@"application",@"wear"]; NSString *filterString = @"SELF LIKE[cd] '*ar'"; //get "ear","wear" filterString = @"SELF LIKE[cd] '?ar'"; //get "ear" filterString = @"SELF LIKE[cd] '?ar?'"; //get "park" filterString = @"SELF LIKE[cd] '?ar*' && SELF ENDSWITH[cd] 'r'"; //get "warrior","ear" filterString = @"SELF BEGINSWITH[cd] 'e' || SELF BEGINSWITH[cd] 's'"; //get "stone","ear"(匹配以"e"或"s"开头的单词) filterString = @"SELF BEGINSWITH[cd] 'app'"; //get "apple","application" filterString = @"SELF ENDSWITH[cd] 'one'"; //get "stone","phone" filterString = @"SELF MATCHES[cd] '^w.+r$'"; //get "warrior","wear"(正则匹配以"w"开头,"r"结尾的单词) NSPredicate *predicate = [NSPredicate predicateWithFormat:filterString]; NSLog(@"过滤结果: %@",[array filteredArrayUsingPredicate:predicate]);
复合条件OR和AND
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"SELF<100"]; NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"SELF<>23"]; NSArray *predicates = [[NSArray alloc]initWithObjects:predicate1,predicate2,nil]; NSPredicate *orCompoundPredicate =[NSCompoundPredicate orPredicateWithSubpredicates:predicates]; NSLog(@"or string:%@",orCompoundPredicate.predicateFormat); //get "SELF < 100 OR SELF != 23" NSPredicate *andCompoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicates]; NSLog(@"and string:%@",andCompoundPredicate.predicateFormat); //get "SELF < 100 AND SELF != 23" [array filterUsingPredicate:andCompoundPredicate]; NSLog(@"filtered array: %@", array); //get [1, 4, 83]
上面的例子都是直接利用SELF比较,如果数组存储的是对象,要以对象的属性值作为筛选目标可以这样:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
NSMutableArray *channelArray = [NSMutableArray array]; TopMenuItem *item = [[TopMenuItem alloc] init]; item.title = @"要闻"; item.order = 1; item.selected = YES; [channelArray addObject:item]; item = [[TopMenuItem alloc] init]; item.title = @"半导体照明"; item.selected = NO; item.order = 5; [channelArray addObject:item]; item = [[TopMenuItem alloc] init]; item.title = @"电子工程"; item.selected = YES; item.order = 2; [channelArray addObject:item]; item = [[TopMenuItem alloc] init]; item.title = @"光通讯"; item.selected = NO; item.order = 3; [channelArray addObject:item]; item = [[TopMenuItem alloc] init]; item.title = @"太阳能光伏"; item.selected = YES; item.order = 4; [channelArray addObject:item]; NSString *filterString = @"title CONTAINS[cd] '光'"; filterString = @"selected==1"; filterString = @"order BETWEEN {3,5}"; NSPredicate *predicate = [NSPredicate predicateWithFormat:filterString]; NSArray *filteredArray = [channelArray filteredArrayUsingPredicate:predicate]; for (TopMenuItem *item in filteredArray) { NSLog(@"%@",item); }