NSArray的排序方法有如下:
- (NSArray *)sortedArrayUsingSelector:(SEL)comparator
- (NSArray *)sortedArrayUsingComparator:(NSComparator)cmptr NS_AVAILABLE(10_6, 4_0)
- (NSArray *)sortedArrayUsingDescriptors:(NSArray *)sortDescriptors
- (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context
第一眼看上去,这确实是四个不同的方法,不过原理是一样的,不管是UsingSelector还是UsingComparator还是UsingFunction其实后面的参数
都是要实现比较的方法。下面我们来看看实例。
1、第一种:
NSArray *testAry = @[@"abcd",@"acbd",@"bacd",@"badc",@"bacd",@"cadb"];
testAry = [testAry sortedArrayUsingSelector:@selector(compare:)];
排序前= (
abcd,
acbd,
bacd,
badc,
bacd,
cadb
)
排序后= (
abcd,
acbd,
bacd,
bacd,
badc,
cadb
)
后面这个compare是一个比较方法(升序),可以比较NSNumber和NSString对象(目前我所知就这两种,欢迎各位添加),返回NSComparisonResult
NSComparisonResult是一个枚举,有三个值NSorderdAscending(升序)、NSorderdSame(相同)、NSorderdDescending(降序)
第二种:
NSArray *testAry3 = @[@"222",@"303",@"203",@"32"];
testAry3 = [testAry3 sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
if ([obj1 integerValue]<[obj2 integerValue]) {
return (NSComparisonResult)NSOrderedAscending;
}
if ([obj1 integerValue]>[obj2 integerValue]) {
return (NSComparisonResult)NSOrderedDescending;
}
return (NSComparisonResult)NSOrderedSame;
}];
像这种,我们要比较的是数组中元素的大小,我们就不能用第一种方法了。第一种方法得到的结果是:
排序后= (
203,
222,
303,
32
)
可以看出来,他并不是比较数字的大小,而是先将第一位排序,然后将第二位排序,以此类推得到上面的结果。而我们是要比较数字的大小,
所以我们可以采用第二种方法。这里我就不详细讲述第二种方法的原理了,第二种方法得到的结果如下:
排序后= (
32,
203,
222,
303
)
上面的例子是比较简单的排序,但是更多的情况是:我们的数组里面并不是存放一个NSString或者NSNumber。
而是一个对象,我们要根据对象的某一个或多个属性将该数组排序。下面我们用一个demo来讲述另外两种方法。
第三种
首先我们有一个model对象,其实现如下:
.h文件的实现
#import <Foundation/Foundation.h>
@interface model : NSObject
@property (nonatomic)NSString *fristName;
@property (nonatomic)NSString *lastName;
@property (nonatomic)NSString *age;
@property (nonatomic)NSString *weight;
- (id)initWithName:(NSString *)fristName lastname:(NSString *)lastName age:(NSString *)age weight:(NSString *)weight;
@end
.m文件的实现
#import "model.h"
@implementation model
- (id)initWithName:(NSString *)fristName lastname:(NSString *)lastName age:(NSString *)age weight:(NSString *)weight
{
self = [super init];
if (self) {
_fristName = fristName;
_lastName = lastName;
_age = age;
_weight = weight;
}
return self;
}
然后我们在ViewController的.m文件中实现如下代码:
说明:创建了两个排序描述(条件),分别是根据fristName和lastName来排序,加入数组的顺序来区分这两个描述的优先级(先加入的优先级高)。
<pre name="code" class="objc"> model * li = [[model alloc] initWithName:@"li" lastname:@"si" age:@"120" weight:@"100"];
model * li1 = [[model alloc] initWithName:@"li" lastname:@"simin" age:@"120" weight:@"100"];
model * zhang = [[model alloc] initWithName:@"zhang" lastname:@"san" age:@"24" weight:@"156"];
model * liu = [[model alloc] initWithName:@"liu" lastname:@"xi" age:@"38" weight:@"34"];
model * cao = [[model alloc] initWithName:@"cao" lastname:@"cao" age:@"100" weight:@"203"];
NSArray *peoples = [NSArray arrayWithObjects:li1,li,zhang,liu,cao, nil];
for (model *people in peoples) {
NSLog(@"<span style="font-family: Arial, Helvetica, sans-serif;">排序前people's name = </span>%@",[NSString stringWithFormat:@"%@ %@",people.fristName,people.lastName]);
}
// 创建描述
NSSortDescriptor *descriptor1 = [[NSSortDescriptor alloc] initWithKey:@"fristName" ascending:YES];
NSSortDescriptor *descriptor2 = [[NSSortDescriptor alloc] initWithKey:@"lastName" ascending:YES];
// 描述数组
NSArray *descriptors = [NSArray arrayWithObjects:descriptor1,descriptor2, nil];
// 根据描述数组进行排序
peoples = [peoples sortedArrayUsingDescriptors:descriptors];
for (model *people in peoples) {
NSLog(@"<span style="font-family: Arial, Helvetica, sans-serif;">排序后people's name = </span>%@",[NSString stringWithFormat:@"%@ %@",people.fristName,people.lastName]);
}
输出结果如下:
排序前people's name = li simin
排序前people's name = li si
排序前people's name = zhang san
排序前people's name = liu xi
排序前people's name = cao cao
排序后people's name = cao cao
排序后people's name = li si
排序后people's name = li simin
排序后people's name = liu xi
排序后people's name = zhang san
第四种:
根据model的age元素来进行排序,weight元素的排序同理:当然我们也可以用第二种方法实现,这里我就不贴了,有兴趣的同学可以自行实现
还是用这个例子,在ViewController中实现如下代码:
<pre name="code" class="objc"> for (model *people in peoples) {
NSLog(@"排序前:age = %@",people.age);
}
peoples = [peoples sortedArrayUsingFunction:customFunction context:nil];
for (model *people in peoples) {
NSLog(@"排序后:age = %@",people.age);
}
customFunction是一个自定义的函数,其的实现如下:
NSInteger customFunction(id obj1, id obj2) {
model *objj1 = (model *)obj1; model *objj2 = (model *)obj2;
if ([objj1.age integerValue]<[objj2.age integerValue]) {
return (NSComparisonResult)NSOrderedAscending;
}
if ([objj1.age integerValue]>[objj2.age integerValue]) {
return (NSComparisonResult)NSOrderedDescending;
}
return (NSComparisonResult)NSOrderedSame;
}
输出结果如下:
排序前:age = 100
排序前:age = 120
排序前:age = 120
排序前:age = 38
排序前:age = 24
排序后:age = 24
排序后:age = 38
排序后:age = 100
排序后:age = 120
排序后:age = 120
有不懂的可以点此下载demo
PS:写博客不多,有错误或者不当的地方,欢迎大家拍砖指正。