学到数组的时候,经常为了数据排序因为排序问题烦恼,楼主也是如此,其实objc为我们提供了很好的排序机制,如下代码加文字来解释一下
通过NSString自带的比较方法排序(也是最简单的方法)
//
// main.m
// NSArraySort (数组排序)博客
//
// Created by YueWen on 15/9/13.
// Copyright (c) 2015年 YueWen. All rights reserved.
//
//首先定义一个数组
NSArray * array = @[@"Boy",@"Array",@"Dary",@"Car"];
/**
* 用里面元素自带的方法进行排序,默认为升序,因为是字符串,所以我们可以用 NSString 拥有的compare方法来进行默认排序
*
* @param compare: 字符串的比较方法compare 返回的类型,在之前的数组文章中也已经讲过了
*
* @return 返回一个接收的数组
*
* 运行结果为: sortArray1 = @[@"Array",@"Boy",@"Car",@"Dary"]
*/
NSArray * sortArray1 = [array sortedArrayUsingSelector:@selector(compare:)];
通过在进行比较时后面的 Block 代码块来进行比较
这种比较相对的比较好用,举个例子来看
升序:
/*
如果是自定义的类进行比较呢 以 Student 为例
我们默认有3个属性
@property(nonatomic,strong)NSString * name;
@property(nonatomic,strong)NSString * studentId;
@property(nonatomic,strong)NSString * age;
*/
//首先定义3个学生
Student * student1 = [[Student alloc]initWithName:@"张三" withStudentId:@"010" withAge:@"12"];
Student * student2 = [[Student alloc]initWithName:@"张三" withStudentId:@"020" withAge:@"11"];
Student * student3 = [[Student alloc]initWithName:@"刺客" withStudentId:@"008" withAge:@"16"];
//添加到数据
NSArray * array2 = @[student1,student2,student3];
/**
* 通过block代码块进行排序,我们可以自定义排序
*
* @param obj1 比较对象的第一对象
* @param obj2 比较对象的第二对象
*
* @return 返回的是比较的结果
*
* 运行结果是:sortArray2 = @[student3,student1,student2];
*/
NSArray * sortArray2 = [array2 sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
//比如我想通过序号id来进行排序
//获取比较的对象(如果不写这两行也可以,在后面的比较处强制转换一下也是可以的)
Student * sObj1 = (Student *)obj1;
Student * sObj2 = (Student *)obj2;
//获取比较的结果,因为是枚举类型,所以不需要加 *(如果需要姓名的排序,当然,这里的对比对象变成name即可,但是比较的双方位置是不可交换的,交换之后比较的结果也会发生变化)
NSComparisonResult result = [sObj1.studentId compare:sObj2.studentId];
//返回结果
return result;
}];
逆序:
//如果我不想按照默认的升序排呢,想降序,当然也是可以的
/**
* 通过block代码块进行排序,我们可以自定义的降序排序
*
* @param obj1 比较对象的第一对象
* @param obj2 比较对象的第二对象
*
* @return 返回的是我们告知它排序的结果
*
* 运行结果是:sortArra2_1 = @[student3,student1,student2];
*/
NSArray * sortArray2_1 = [array2 sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
//这次我们就按照年龄排序吧
//依旧获取对象
Student * sObj1 = (Student *)obj1;
Student * sObj2 = (Student *)obj2;
//获取比较结果
NSComparisonResult result = [sObj1.age compare:sObj2.age];
switch (result) {
//如果是升序,那么就表示前边的小,那么我们就告知它需要降序
case NSOrderedAscending:
return NSOrderedDescending;
break;
//如果是降序,那么就表示前边的元素大,我们就告知它是升序,就不需要交换了
case NSOrderedDescending:
return NSOrderedAscending;
break;
//如果是相等,那么我们就不需要排序了,也就告知它确实是相等的就可以
case NSOrderedSame:
return NSOrderedSame;
break;
default:
break;
}
}];
NSSortDescriptor排序
其实现在看来,这种排序方法一般用来解决比较复杂的结构问题,比如复合排序问题,但是描述却是很简单的,看代码量比第二种方法少了不少,一般的排序上面的两种都可以解决的,但是为了好理解,用了一个比较简单的实例来展示一下,代码如下:
/*
如果我们想先通过年龄排序,如果相同,我们再按照姓名进行排序呢
当然,这种排序也是可以的
那么我们需要用到另一种类型: 叫做NSSortDescriptor (排序描述)
*/
//首先我们为了验证,我们需要改一下我们之前的Student类对象
/*
//首先定义3个学生
Student * student1 = [[Student alloc]initWithName:@"张三" withStudentId:@"010" withAge:@"12"];
Student * student2 = [[Student alloc]initWithName:@"张三" withStudentId:@"009" withAge:@"11"];
Student * student3 = [[Student alloc]initWithName:@"刺客" withStudentId:@"008" withAge:@"16"];
那么我们的需求是什么呢,先按照名字升序,如果名字相同,那么我们就要看年龄
*/
//首先我们先把student加到数组中
NSArray * array3 = @[student1,student2,student3];
/**
* 然后就要定义我们的排序描述了
* 以下的意思就是说,我对比的凭据是 name 属性, ascending 是否升序排列
*/
NSSortDescriptor * descriptor1 = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
NSSortDescriptor * descriptor2 = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES];
/**
* 我们为数组添加排序描述
* 首先我们按照第1个描述来排列,如果相等,我们再会按照第2个排序描述来排序
*
* 运行结果是: sortArray3 = @[student3,student2,student1];
*/
NSArray * sortArray3 = [array3 sortedArrayUsingDescriptors:@[descriptor1,descriptor2]];