OC语言 - 数组 | 数组排序
数组
1 - OC 中的数组只能存放对象,不能存放非对象,如 int、结构体、枚举等
① NSArray
1 NSArray * array01 = [NSArray arrayWithObjects:@"A",@"B",@"C", nil]; 2 NSLog(@"%@",array01); 3 4 NSArray * array02 = [[NSArray alloc] initWithObjects:@"小",@"简直",@"了",@"白", nil]; 5 NSLog(@"%@",array02); 6 7 NSLog(@"array02 count = %ld",[array02 count]);// 数组个数 8 NSString * str01 = [array02 objectAtIndex:1]; // 按照下标获取数组元素 9 NSLog(@"str01 = %@",str01); 10 11 // 遍历数组 12 for (int i = 0; i< [array02 count]; i++) { 13 14 NSString * str02 = [array02 objectAtIndex:i]; 15 NSLog(@"%@",str02); 16 }
② NSMutableArray
// - Person.h
1 #import <Foundation/Foundation.h> 2 @interface Person : NSObject{ 3 NSString *_name; 4 NSString *_sex; 5 NSInteger _age; 6 } 7 8 // 输出性别、姓名、年龄 9 - (void)sayHi; 10 11 - (NSString *)name; 12 - (NSString *)sex; 13 - (NSInteger )age; 14 15 - (id)initWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age; 16 17 18 @end
// - Person.m
1 #import "Person.h" 2 @implementation Person 3 - (void)sayHi{ 4 NSLog(@"姓名:%@,性别:%@,年龄:%ld",_name,_sex,_age); 5 } 6 7 - (id)initWithName:(NSString *)name 8 sex:(NSString *)sex 9 age:(NSInteger)age{ 10 self = [super init]; 11 if (self) { 12 _name = name; 13 _sex = sex; 14 _age = age; 15 } 16 return self; 17 } 18 19 - (NSString *)description{ 20 return [NSString stringWithFormat:@"%@,%@,%ld",_name,_sex,_age]; 21 } 22 23 @end
// - main.m
1 #import <Foundation/Foundation.h> 2 #import "Person.h" 3 int main(int argc, const char * argv[]) { 4 5 // 创建多个 Person 实例对象 6 Person *person01 = [[Person alloc] initWithName:@"Liu" sex:@"m" age:15]; 7 Person *person02 = [[Person alloc] initWithName:@"Chen" sex:@"f" age:92]; 8 Person *person03 = [[Person alloc] initWithName:@"Zhang" sex:@"m" age:35]; 9 Person *person04 = [[Person alloc] initWithName:@"Li" sex:@"f" age:84]; 10 Person *person05 = [[Person alloc] initWithName:@"Wang" sex:@"m" age:51]; 11 12 13 // 同一对象可以在数组中存放多次 14 NSArray *array03 = [[NSArray alloc] initWithObjects:person01,person02,person03,person04,person05,person02, person02,nil]; 15 NSLog(@"%@",array03); 16 /* 输出 17 ( "Liu,m,15", 18 "Chen,f,92", 19 "Zhang,m,35", 20 "Li,f,84", 21 "Wang,m,51", 22 "Chen,f,92", 23 "Chen,f,92" 24 ) 25 */ 26 27 // 遍历 array03 28 for (int i = 0; i< [array03 count]; i++) { 29 30 Person * per = [array03 objectAtIndex:i]; 31 NSLog(@"%@",per); 32 } 33 34 35 // 数组可以存放不同的对象 36 NSArray *array04 = [[NSArray alloc] initWithObjects:person01,person02,@"Fuck",person03,@"Be civilization",person04,person05, nil]; 37 // 是否是 Person 型对象 38 for (int i = 0 ; i<[array04 count]; i++) { 39 // id 类型 40 id Obj = [array04 objectAtIndex:i]; 41 42 // isKindOfClass 43 if ([Obj isKindOfClass:[Person class]]) { 44 45 [Obj sayHi]; 46 }else{ 47 48 NSString *str = [array04 objectAtIndex:i]; 49 NSLog(@"非 Person 对象:%@",str); 50 } 51 } 52 53 54 // containsObject:是否包含某对象 55 BOOL res01 = [array04 containsObject:person04]; 56 NSLog(@"%@",res01 ? @"YES":@"NO"); 57 58 59 // indexOfObject:获取某对象在数组中的索引 60 NSUInteger index = [array04 indexOfObject:person03]; 61 NSLog(@"%lu",index); 62 63 64 // 获取数组的第一个/最后一个对象 65 Person *firstPerson = [array04 firstObject]; 66 Person *lastPerson = [array04 lastObject]; 67 NSLog(@"数组的第一个对象:%@,数组的最后一个对象:%@",firstPerson,lastPerson); 68 69 70 // 当内存不够的时候,系统自动会追加内存 71 NSMutableArray *arr05 = [NSMutableArray arrayWithCapacity:1]; 72 [arr05 addObject:person01]; 73 [arr05 addObject:person02]; 74 [arr05 addObject:person03]; 75 [arr05 addObject:person04]; 76 [arr05 addObject:person05]; 77 NSLog(@"%@",arr05); 78 [arr05 insertObject:@"Zhao" atIndex:3];// 插入 79 NSLog(@"%@",arr05); 80 81 // replaceObjectAtIndex:替换数组中的对象 82 [arr05 replaceObjectAtIndex:3 withObject:@"Zhou"]; 83 NSLog(@"%@",arr05); 84 85 // exchangeObjectAtIndex:交换两个下标的对象 86 [arr05 exchangeObjectAtIndex:2 withObjectAtIndex:3]; 87 NSLog(@"%@",arr05); 88 89 // 删除数组中的某个对象:重复的对象会全部移除 90 [arr05 removeObject:person02]; 91 NSLog(@"%@",arr05); 92 93 // 删除数组中某个位置的对象 94 [arr05 removeObjectAtIndex:3]; 95 NSLog(@"%@",arr05); 96 97 // 删除从某个范围的对象 98 [arr05 removeObjectsInRange:NSMakeRange(1, 2)]; 99 NSLog(@"%@",arr05); 100 101 // 删除数组中所有的对象 102 [arr05 removeAllObjects]; 103 NSLog(@"%@",arr05); 104 105 return 0; 106 }
注:for...in... 是不允许对可变容器的对象进行增删操作!若想要增删对象,可以考虑使用 for 循环
1 NSMutableArray *array99 = [[NSMutableArray alloc] initWithObjects:person01,person02,person03,person04,person05,nil]; 2 for (Person *person in array99) { 3 if ([person age] < 24) { 4 [array99 removeObject:person]; // 程序 crash 5 } 6 }
数组排序
1 - block 排序
1 NSArray *array = [NSArray arrayWithObjects:@"A",@"B",@"C", nil]; 2 3 // block 遍历:每遍历到一个元素,就会调用一次 block,并且把当前元素和索引当作参数传给 block 4 [array enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 5 6 NSLog(@"%lu - %@",(unsigned long)idx,obj); 7 // 停止遍历 8 if (idx == 1) { 9 *stop = YES; 10 } 11 }];
我们可简单推测一下 block 遍历内部原理
1 void (^myblock)(id,NSUInteger,BOOL *)= ^(id obj, NSUInteger idx, BOOL *stop){ 2 3 NSLog(@"%ld - %@", idx,obj); 4 if (idx == 1) { 5 *stop = YES; 6 } 7 8 }; 9 10 11 NSArray *arrayTest = [NSArray arrayWithObjects:@"A",@"B",@"C", nil]; 12 13 for (int i = 0; i < (int)array.count; i ++) { 14 BOOL isStop = NO;// 标记是否需要停止遍历 15 16 id obj = arrayTest[i];// 获取元素 17 myblock(obj,i,&isStop); 18 if (isStop) { 19 break; 20 } 21 22 }
2 - 使用自定义方法实现数组排序
// - Person.h
1 #import <Foundation/Foundation.h> 2 @interface Person : NSObject{ 3 NSString *_name; 4 NSString *_sex; 5 NSInteger _age; 6 } 7 8 - (NSString *)name; 9 - (NSString *)sex; 10 - (NSInteger )age; 11 12 - (id)initWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age; 13 14 // 按照年龄排序 15 - (NSComparisonResult)sortByAge:(Person *)person; 16 17 // 按照姓名排序 18 - (NSComparisonResult)sortByName:(Person *)person; 19 20 @end
// - Person.m
1 #import "Person.h" 2 @implementation Person 3 4 5 - (id)initWithName:(NSString *)name 6 sex:(NSString *)sex 7 age:(NSInteger)age{ 8 self = [super init]; 9 if (self) { 10 _name = name; 11 _sex = sex; 12 _age = age; 13 } 14 return self; 15 } 16 17 - (NSString *)description{ 18 return [NSString stringWithFormat:@"%@,%@,%ld",_name,_sex,_age]; 19 } 20 21 - (NSString *)name{ 22 return _name; 23 } 24 25 - (NSString *)sex{ 26 return _sex; 27 } 28 29 - (NSInteger )age{ 30 return _age; 31 } 32 33 // 按照年龄排列 34 - (NSComparisonResult)sortByAge:(Person *)person{ 35 36 // // 升序排列 37 // if (_age < [person age]) { 38 // return NSOrderedAscending; 39 // }else if (_age > [person age]){ 40 // return NSOrderedDescending; 41 // } 42 43 // 降序排列 44 if ([person age] < _age) { 45 return NSOrderedAscending; 46 }else if ([person age]>_age){ 47 return NSOrderedDescending; 48 } 49 50 return NSOrderedSame; 51 } 52 53 // 按照姓名排除 54 - (NSComparisonResult)sortByName:(Person *)person{ 55 56 // 升序 57 return [_name compare:[person name]]; 58 59 // 降序 60 // return [[person name] compare:_name]; 61 62 } 63 64 65 @end
// - main.m
1 #import <Foundation/Foundation.h> 2 #import "Person.h" 3 int main(int argc, const char * argv[]) { 4 5 // 方式一:系统方法,只限于字符串 6 NSArray *array088 = [NSArray arrayWithObjects:@"Bruce",@"Jason",@"Hazell",@"Mark",@"Jicyy",@"Lucy",@"Rose",@"Solina", nil]; 7 NSArray *newArray088 = [array088 sortedArrayUsingSelector:@selector(compare:)]; 8 NSLog(@"compare:%@",newArray088);// (Bruce, Hazell, Jason, Jicyy, Lucy, Mark, Rose, Solina) 9 10 11 // 方式二:自定义方法 12 Person *person01 = [[Person alloc] initWithName:@"Liu" sex:@"m" age:15]; 13 Person *person02 = [[Person alloc] initWithName:@"Chen" sex:@"f" age:92]; 14 Person *person03 = [[Person alloc] initWithName:@"Zhang" sex:@"m" age:35]; 15 Person *person04 = [[Person alloc] initWithName:@"Li" sex:@"f" age:84]; 16 Person *person05 = [[Person alloc] initWithName:@"Wang" sex:@"m" age:51]; 17 // 把对象放进数组 18 NSArray *array05 = [NSArray arrayWithObjects:person01,person02,person03,person04,person05,nil]; 19 20 // 按照年龄排序:降序 21 NSArray *newArray04 = [array05 sortedArrayUsingSelector:@selector(sortByAge:)]; 22 NSLog(@"sortByAge:%@",newArray04);// ("Chen,f,92", "Li,f,84", "Wang,m,51", "Zhang,m,35", "Liu,m,15") 23 24 // 按照姓名排序:升序 25 NSArray *array06 = [array05 tor(sortByName:)]; 26 NSLog(@"sortByName:%@",array06);//("Chen,f,92", "Li,f,84", "Liu,m,15", "Wang,m,51", "Zhang,m,35") 27 28 return 0; 29 }
3 - 高级排序 sortedArrayUsingDescriptors
① 如果说有这样一种情况:Person 里有另外一个 Class 的变量,比如 Person 除了 name、age,还有一 Car 型实成员变量,而 Car 里还有 name 属性,那么在对 Person 实例对象进行排序时,要求:如果是同一辆车(以车名区分为例),则按照年龄进行排序;如果年龄相同,则按人名排序
② 代码实现
// - Car.h
1 #import <Foundation/Foundation.h> 2 @interface Car : NSObject 3 4 @property(nonatomic,copy)NSString *name;// 车名 5 6 +(Car *)initWithName:(NSString *)name; 7 8 @end
// - Car.m
1 #import "Car.h" 2 @implementation Car 3 4 +(Car *)initWithName:(NSString *)name{ 5 6 Car *car = [[Car alloc] init]; 7 car.name = name; 8 return car; 9 10 } 11 12 @end
// - Person.h
1 #import <Foundation/Foundation.h> 2 @class Car; 3 @interface Person : NSObject 4 5 @property(nonatomic,copy)NSString *name; 6 @property(nonatomic,strong)Car *car; 7 @property(nonatomic,assign)int age; 8 9 +(Person*)personWithAge:(int)age withName:(NSString *)name withCar:(Car *)car; 10 11 @end
// - Person.m
1 #import "Person.h" 2 #import "Car.h" 3 @implementation Person 4 5 +(Person*)personWithAge:(int)age withName:(NSString *)name withCar:(Car *)car{ 6 7 Person *person = [Person new]; 8 person.age = age; 9 person.name = name; 10 person.car = car; 11 12 return person; 13 14 } 15 16 -(NSString*)description{ 17 18 return [NSString stringWithFormat:@"age is %d , name is %@, car is %@",_age,_name,_car.name]; 19 } 20 @end
// - main.m
1 #import <Foundation/Foundation.h> 2 #import "Person.h" 3 #import "Car.h" 4 int main(int argc, const char * argv[]) { 5 6 // 搞 4 辆车 7 Car *car1 = [Car initWithName:@"Audio"]; 8 Car *car2 = [Car initWithName:@"Rolls-Royce"]; 9 Car *car3 = [Car initWithName:@"BMW"]; 10 Car *car4 = [Car initWithName:@"BYD"]; 11 12 13 // 搞 5 个靓仔,人手一辆车 14 Person*p1 = [Person personWithAge:23 withName:@"Linda Lusardi" withCar:car3]; 15 Person*p2 = [Person personWithAge:13 withName:@"Samantha Fox" withCar:car4]; 16 Person*p3 = [Person personWithAge:13 withName:@"Melinda Messenger" withCar:car2]; 17 Person*p4 = [Person personWithAge:22 withName:@"Keeley Hazell" withCar:car3]; 18 Person*p5 = [Person personWithAge:30 withName:@"Joanne Guest" withCar:car1]; 19 20 NSArray *array = [NSArray arrayWithObjects:p1,p2,p3,p4,p5, nil]; 21 22 // 排序描述器 23 NSSortDescriptor *carNameDesc = [NSSortDescriptor sortDescriptorWithKey:@"car.name" ascending:YES]; 24 NSSortDescriptor *personNameDesc = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]; 25 NSSortDescriptor *personAgeDesc = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES]; 26 27 // 把排序描述器放进数组,注意:放入的顺序就是你想要排序的顺序 28 // 这里是首先按照年龄排序、然后是车的名字、最后是按照人的名字 29 NSArray *descriptorArray = [NSArray arrayWithObjects:personAgeDesc,carNameDesc,personNameDesc, nil]; 30 NSArray *sortedArray = [array sortedArrayUsingDescriptors: descriptorArray]; 31 NSLog(@"%@",sortedArray); 32 return 0; 33 }
日志信息
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律