今天浏览到一位仁兄的帖子,提到了NSArray排序的问题,就根据自己总结写下了此篇帖子,同时附上自己的小demo,介绍一下NSArray关于排序方面的比对。个人感觉不适什么高深的知识,算是对api的使用。我归结为四种方法。
- 手写for循环式
- 简单排序(sortedArrayUsingSelector:)
- block语法式排序(sortedArrayUsingComparator:)
- 高级排序(sortedArrayUsingDescriptors:)
1.手写for循环式
看标题就能理解,就是我们写一个array然后用for循环的方式进行排序,期间还要用到排序算法。看上去很高深其实是最笨的方法,如果对NSArray熟悉的话,NSArray造就提供了相关的api供我们使用。
// 冒泡排序法进行排序 时间复杂度在n*n
NSMutableArray *array = [NSMutableArray arrayWithObjects:@233,@151,@23,@998,@775, nil];
for (NSInteger i = 0; i < array.count ; i++)
{
for (NSInteger j = i; j < array.count; j++)
{
NSNumber *model_i = array[i];
NSNumber *model_j = array[j];
if(model_i.intValue > model_j.intValue)
{
//交换
[array replaceObjectAtIndex:i withObject:model_j];
[array replaceObjectAtIndex:j withObject:model_i];
}
}
}
NSLog(@"冒泡排序:%@",array);
在demo里面我用了冒泡排序进行排序,他的时间复杂度是n的平方。
2.简单排序(sortedArrayUsingSelector:)
如果只是针对见的字符串或者NSNumber,我们利用sortedArrayUsingSelector:方法就可以满足我们的需求了。上代码:
NSArray *array = [NSArray arrayWithObjects:@233,@151,@23,@998,@775, nil];
NSArray *sortedArray = [array sortedArrayUsingSelector:@selector(compare:)];
NSLog(@"排序后:%@",sortedArray);
这里我们用到了NSNumber自带的compare:方法,短短的两行代码就解决了第一种方法中要解决的问题。
当然我们还可以自己定义比较的方法和规则。代码如下:
我们首先创造一个Person类
+ (id)personWithName:(NSString *)name andAge:(int)age {
Person *person = [[Person alloc] init];
person.age = age;
person.name = name;
return person;
}
//自定义排序方法
-(NSComparisonResult)comparePerson:(Person *)person{
//默认按年龄排序
NSComparisonResult result = [[NSNumber numberWithInt:person.age] compare:[NSNumber numberWithInt:self.age]];//注意:基本数据类型要进行数据转换
//如果年龄一样,就按照名字排序
if (result == NSOrderedSame) {
result = [self.name compare:person.name];
}
return result;
}
- (NSString *)description {
return self.name;
}
主函数代码:
Person *p1 = [Person personWithName:@"zhangsan" andAge:23];
Person *p2 = [Person personWithName:@"lisi" andAge:21];
Person *p3 = [Person personWithName:@"wangwu" andAge:24];
Person *p4 = [Person personWithName:@"zhaolilu" andAge:24];
Person *p5 = [Person personWithName:@"wangermazi" andAge:20];
NSArray *array = [NSArray arrayWithObjects:p1,p2,p3,p4,p5, nil];
NSArray *sortedArray = [array sortedArrayUsingSelector:@selector(comparePerson:)];
NSLog(@"排序后:%@",sortedArray);
3.block语法式排序(sortedArrayUsingComparator:)
苹果官方提供的block语法,用到了sortedArrayUsingComparator:方法,比较简单,代码如下:
NSArray *array = [NSArray arrayWithObjects:@233,@151,@23,@998,@775, nil];
NSArray *sortedArray = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
//这里的代码可以参照上面compare:默认的排序方法,也可以把自定义的方法写在这里,给对象排序
NSComparisonResult result = [obj1 compare:obj2];
return result;
}];
NSLog(@"block排序后:%@",sortedArray);
4.高级排序(sortedArrayUsingDescriptors:)
在这里我们就要用到上文提到的Person类了。Person类里有另外一个类的变量,比如说Person类除了name,age变量,还有一辆车Car类型,Car类里有个name属性。对Person对象进行排序,有这样的要求:按照Car的name排序,如果是同一辆车,也就是Car的name相同,那么再按照年龄进行排序,如果年龄也相同,最后按照Person的name进行排序。那这种情况下我有实现了一个HasCarPerson, HasCarPerson继承自Person类。
上面这样就要使用第三种方法,利用排序描述器,不多说,有兴趣可以看看API介绍。代码如下:
首先写一个Car类,Car.m文件代码如下:
@interface Car()
@property (nonatomic, strong) NSString *name;
@end
@implementation Car
+ (Car *)initWithName:(NSString *)name{
Car *car = [[Car alloc] init];
car.name = name;
return car;
}
@end
然后实现HasCarPerson类,HasPerson.m类代码如下:
@interface HasCarPerson()
@property (nonatomic, strong) Car *car;
@end
@implementation HasCarPerson
+(HasCarPerson *)personWithAge:(int)age withName:(NSString *)name withCar:(Car *)car {
HasCarPerson *person = [[HasCarPerson alloc] init];
person.age = age;
person.name = name;
person.car = car;
return person;
}
//这里重写description方法,用于最后测试排序结果显示
-(NSString *)description{
return [NSString stringWithFormat:@"age is %zi , name is %@, car is %@", self.age, self.name, _car.name];
}
"age is 21 , name is zhangsan, car is Audio",
"age is 23 , name is wangwu, car is BMW",
"age is 23 , name is wangwu, car is Rolls-Royce",
"age is 23 , name is zhangsan, car is Rolls-Royce",
"age is 24 , name is lisi, car is Audio"