当前位置:网站首页>[OC-Foundation框架]---【集合数组】
[OC-Foundation框架]---【集合数组】
2022-07-06 08:50:00 【关于小司】
文章目录
OC的集合概述
- OC的集合类可以用于存储多个数量不相等的对象并可以实现常用的数据结构
- OC集合大致上可以分为 NSArray,NSSet, NSDictionary三种
- NSArray,有序可重复的集合
- ,NSSet 无序不可重复的集合
- ,NSDictionary 具有映射关系的集合
数组 NSArray 与可变数组 NSMutableArray
NSArray提供了类方法和实例方法来创建NSArray,两种方法需要传入的参数基本相似
类方法以array开头 实例方法以init开头
创建NSArray的几类方法
array:创建一个不包含任何元素的空 NSArray。
array WithContentsOfFile:/nit With ContentsOfFile::读取文件内容来创建 NSArray
array WithObject:/initwithObject: 创建只包含指定元素的 - NSArray。
array WithObjects:/initWithObjecti: 创建包含指定的 入 个元素的 NSArray。
除此之外,还可使用如不简化语法来创建 NSArray对象。 NSArray *array = @[,]
创建代码
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSArray* array = [NSArray arrayWithObjects:@"3g",@"Android", @"Ajax", @"XML", @"Swift", nil];
NSLog(@" 第一个元素 %@", array[0]);
NSLog(@" 最后一个元素 %@", [array lastObject]);
//从获取索引为2的元素开始,以及后面三个元素组成的集合
NSArray *arr1 = [array objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(2, 3)]];
NSLog(@" %@", arr1);
// 获取元素俄在集合的位置
NSLog(@" 元素Ajax的位置是 : %ld", [array indexOfObject:@"Ajax"]);
// 获取元素在集合指定范围中的位置
NSLog(@"在2-5范围Android的位置是 %ld", [array indexOfObject:@"Android"inRange:NSMakeRange(2, 3)]);
//集合[16654:2344761] 在2-5范围Android的位置是 9223372036854775807
// 找不到
// 其实这也是常量NSNotFound的值
// 追加元素
// 类似字符串NSArray本身不变,将新返回的NSArray赋值给 array
array = [array arrayByAddingObject:@"神奇的iOS"];
// 向数组的最后追加两一个新数组的所有元素
//类似字符串NSArray本身不变,将新返回的NSArray赋值给 array
array = [array arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:@"神奇的不省人室222", @"s神奇的复杂化", @"神奇的我", nil]];
for (int i= 0; i < array.count; i++) {
// NSLog(@"%@-", [array objectAtIndex:i]);
NSLog(@"%@", array[i]);
// 学习了c熟悉第二种数组用法!
}
// 将数组集合写入文件
[arr1 writeToFile:@"myFile.txt" atomically:YES];
}
return 0;
}
操作详解
1)遍历集合元素
objectAtIndex:index或者 array[i]
推荐使用后者
2)向NSArray后追加元素
arrayByAddingObject:--追加单个元素
arrayWithObjexts: 方法将另一个数组的所有元素追加至数组后面
3)值得一提的是 我们NSArray数组是不可变的所以只要是改变数组内部的值的方法都是开辟一个新空间然后把数组指针指向新的数组而不是在旧数组操作
查看NSArray数组的几种操作
- 查询集合元素在 NSArray 中的索引。
- 根据索引值取出 NSArray 集合中的元素。
- 对集合元素整体调用方法。
- 对 NSArray 集合进行排序。
NSArray 如何判断集合是否包含制定元素
- 标准只有一条: 这就用到我们之前学习的isEqual方法了当比较返回了YES,才可以认为该NSArray集合包含
该元素,并不需要两个元素是同一个元素;
NSArray的比较机制
重写isEqual
- 我们为了验证比较机制 创建一个FKUser对象
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface FKUser : NSObject
@property (nonatomic, copy) NSString* name;
@property (nonatomic, copy) NSString* pass;
- (id) initWithName : (NSString*) aName pass:(NSString*) aPass;
- (void) say:(NSString*) content;
@end
NS_ASSUME_NONNULL_END
#import "FKUser.h"
@implementation FKUser
- (id) initWithName:(NSString *) name pass:(NSString *) pass {
if (self = [super init]) {
self->_name = name;
self->_pass = pass;
}
return self;
}
- (void) say: (NSString*) content {
NSLog(@" %@ 用无敌嗓音大声吼叫道:%@", self.name, content);
}
//重写比较方法,可以比较标准是如果两个FKUSer的name pass相等 即可认为它们相等
- (BOOL) isEqual:(id) other {
if (self == other) {
return YES;
} else if ([other class] == FKUser .class) {
FKUser* target = (FKUser*)other;
return [self.name isEqualToString:target.name] &&[self.pass isEqualToString:target.pass];
}
return NO;
}
@end
- 注意我们自定义了isEqual的标准,重写比较方法,可以比较标准是如果两个FKUSer的name pass相等 即可认为它们相等
测试isEuqal
#import <Foundation/Foundation.h>
#import "FKUser.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//创建NSArray对象
NSArray* array = @[
[[FKUser alloc] initWithName:@"sun" pass:@"123"],
[[FKUser alloc] initWithName:@"bai" pass:@"345"],
[[FKUser alloc] initWithName:@"zhu" pass:@"654"],
[[FKUser alloc] initWithName:@"tang" pass:@"178"],
[[FKUser alloc] initWithName:@"niu" pass:@"155"]];
//查找指定新FKUser对象在集合里的索引
FKUser* newUser = [[FKUser alloc] initWithName:@"zhu" pass:@"654"];
NSUInteger pos = [array indexOfObject:newUser];
NSLog(@" 查找到newUser的位置为 %ld", pos);
}
return 0;
}
- 我们测试的例子是创建一个 FKUser对象 这个对象虽然不是我们数组里的对象之一 但是它和数组里的某个对象有着相同属性满足重写之后的isEqual方法即可
对NSArray排序
NSArray 提供了三种排序
- sortedArrayUsingFunction:context::使用排序函数对集合元素进行排序,函数必须返回NSOrderedDescending、NSOrderedAscending、NSorderedSame这些枚举值,用于代表集合元素的大小。该方法返回一个排序好的新NSArray对象。
- sortedArrayUsingSelector::使用集合元素自身的方法对集合元素进行排序,函数必须返回NSOrderedDescending、NSOrderedAscending、NSorderedSame这些枚举值,用于代表集合元素的大小。该方法返回一个排序好的新NSArray对象。
- sortedArrayUsingComparator::使用代码块对集合元素进行排序,函数必须返回NSOrderedDescending、NSOrderedAscending、NSorderedSame这些枚举值,用于代表集合元素的大小。该方法返回一个排序好的新NSArray对象。
//----------------------------
// 对NSArray 进行排序
#import <Foundation/Foundation.h>
#import "FKUser.h"
// 定义比较函数 根据对象的intValue进行比较
NSComparisonResult intSort (id num1, id num2, void *context) {
int val1 = [num1 intValue];
int val2 = [num2 intValue];
if (val1 < val2) {
return NSOrderedAscending;
} else if (val1 > val2) {
return NSOrderedDescending;
} else if (val1 == val2) {
return NSOrderedSame;
}
return 0;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSArray *array = @[@"Objective-C", @"C", @"C++", @"Ruby", @"Perl", @"Swift"];
// 使用集合元素compare方法排序
array = [array sortedArrayUsingSelector:@selector(compare:)];
NSLog(@"%@ ", array);
//初始化一个元素为NSNumber 的NSAarray对象
NSArray* arr2 = @[
[NSNumber numberWithInt:20],
[NSNumber numberWithInt:12],
[NSNumber numberWithInt:-8],
[NSNumber numberWithInt:50],
[NSNumber numberWithInt:19]
];
//使用insort排序
arr2 = [arr2 sortedArrayUsingFunction:intSort context:nil];
NSLog(@"%@", arr2);
// 使用代码块对集合元素进行排序
NSArray* arr3 = [arr2 sortedArrayUsingComparator:^(id obj1, id obj2){
if ([obj1 intValue] > [obj2 intValue]) {
return NSOrderedDescending;
} else if ([obj1 intValue] < [obj2 intValue]) {
return NSOrderedAscending;
}
return NSOrderedSame;
}];
NSLog(@" %@", arr3);
}
return 0;
}
排序注意之处
- 对于三种排序方法 第2种是我们自己写内部判断标准,
- 第三种针对块也是自己写内部标准
- 集合元素本身可以比较大小,而且直接利用集合元素比较大小的方法进行排序的方法称为自然排序;对于通过比较函数或代码块来指定自定义比较规则的方式,则被称为定制排序。
枚举遍历NSArray集合元素
顺逆序枚举
对于 NSArray对象,除了 可根据集 合元素的索引来遍历集合元素之外,还可以调用NSArray 对象的如下两个方法来返回枚举器。
- objectEnumerator:返回 NSArray 集合的顺序枚举器。
- reverseObjectEnumerator:返回 NSArray 集合的逆序枚举器
上面两个方法都返回一个 NSEnumerator 枚举器,该枚举器只包含如下两个方法
allobjects:获取被枚举集合中的所有元素。
nextObiect:获取被枚举集合中的下一个元素。
一般来说,借助 nextObeiat 方法即可对集合元素进行枚举:程序可采用循环不断获取nextObject 方法的返回值,直到该方法的返回值为 nil 结束循环。
// 7.5.4----正逆序枚举
#import <Foundation/Foundation.h>
#import "FKUser.h"
int main( int argc, char* argv[]) {
@autoreleasepool {
// 读取文件 在之前写过的文件
NSArray *array = [NSArray arrayWithContentsOfFile:@"myFile.txt"];
// 获取NSArray 的顺序枚举器
NSEnumerator *en = [array objectEnumerator];
id object;
while (object = [en nextObject]) {
NSLog(@"%@", object);
}
NSLog(@"获取逆序枚举器");
en = [array reverseObjectEnumerator];
while (object = [en nextObject]) {
NSLog(@" %@", object);
}
}
}
快速枚举
快速枚举(for - in)
OC-提供了一种快速枚举的方法来便利集合 使用快速枚举方法遍历集合无需获得集合的长度,也无需根据索引来访问集合元素 即可快速枚举遍历集合的每个元素
语法入下
for (type variableName in collection) {
variableName 自动访问每个元素
}
type是 集合元素类型 variableName是一个形参名 ,通过快速枚举将自动将集合元素依次赋值给该形参变量
#import <Foundation/Foundation.h>
#import "FKUser.h"
int main( int argc, char* argv[]) {
@autoreleasepool {
NSArray *array = [NSArray arrayWithContentsOfFile:@"myFile.txt"];
for (id object1 in array) {
NSLog(@"%@", object1);
}
}
}
关于快速枚举
从上面的程序可以看出 使用快速枚举遍历数组元素不需要获得数组长度 也无需根据索引来访问数组元素
本质是(for-each)循环
for each
这种循环无需循环条件 无需迭代循环语句 当每个元素都被迭代一次之后 循环自动结束
可变数组(NSMutableArray)
和NSArray不一样的地方
- NSArray 代表了不可变的集合 一旦NSArray创建成功 程序就不能向集合中添加新的元素,不能删除集合中已有的元素,也不能替换集合元素
- 注意 NSArray 只是保存了对象的指针,因此NSArray 只保证这些指针变量地址不改变,但指针变量所指向的对象是可以改变的
- NSMutableArray是NSArray的子类 ,因此它可以作为NSArray使用
新的操作
NSMutableArray代表的是一个集合元素可变的集合,而NSMutableArray底层采用了传统数组来容纳集合元素
因此 创建一个NSMutableArray 集合时可以通过参数指定底层数组的容纳量
NSMutableArray新增的方法
- 添加集合元素;add开头
- 删除集合元素 remove开头
- 替换集合元素 replace开头
- 对集合本身排序方法 sort开头
NSMutableArray是NSArray的子类 所以他也有3个排序 注意NSMutableArra是可变数组集合 所以它返回的是本身 (可以认为对集合本身排序)
NSArray则是 返回一个新的排序好的NSArray对象
NSArray 的KVC 和KVO(此文章不做解释,暂时没有学习到监听有关知识)
NSArray 的KVC
- NSArray 允许直接对集合中的所哟元素进行整体的KVC编码,NSArray提供了如下两种编码
- setValue: forKey: 将集合中所有元素指定的key 对应属性或者实例变量设置为value
- valueForKey: 返回该NSArray集合中所有元素的指定key组成的NSArray对象
#import <Foundation/Foundation.h>
#import "FKUser.h"
// 定义一个函数 把NSArray集合转换为字符串
NSString* NSCollectToString(NSArray *array) {
NSMutableString* result = [NSMutableString stringWithString:@"["];
for (id obj1 in array) {
[result appendString:[obj1 description]];
[result appendString:@", "];
}
// 获取字符串长度
NSUInteger len = [result length];
//弃掉字符串最后的两个字符
[result deleteCharactersInRange:NSMakeRange(len-2, 2)];
[result appendString:@"]"];
return result;
}
int main( int argc, char* argv[]) {
@autoreleasepool {
NSArray *array = @[
[[FKUser alloc]initWithName:@"sun" pass:@"123"],
[[FKUser alloc]initWithName:@"bai" pass:@"345"],
[[FKUser alloc]initWithName:@"zhu" pass:@"654"],
[[FKUser alloc]initWithName:@"tang" pass:@"178"],
[[FKUser alloc]initWithName:@"niu" pass:@"155"],
];
// 获取所有集合元素的name属性组成的新集合
id newArr = [array valueForKey:@"name"];
NSLog(@"%@", NSCollectToString(newArr));
// for (int i = 0; i < array.count; i++) {
// NSLog(@"%@", newArr[i]);
// }
//对集合的所有元素进行KVC编程
//对所所有集合元素的name属性改为“新名字’
[array setValue:@"李育腾" forKey:@"name"];
// NSLog(@"%@", NSCollectToString(array));
for (int i = 0; i < array.count; i++) {
NSLog(@"%@", array[i]);
}
}
}
奇怪的打印
打印结果没有把数组元素本身性质描述出来
打印结果如下的原因是我没有重写关于description方法
重写description方法后的结果
边栏推荐
- Fairguard game reinforcement: under the upsurge of game going to sea, game security is facing new challenges
- hutool优雅解析URL链接并获取参数
- 个人电脑好用必备软件(使用过)
- 超高效!Swagger-Yapi的秘密
- 有效提高软件产品质量,就找第三方软件测评机构
- LeetCode:673. Number of longest increasing subsequences
- TP-LINK enterprise router PPTP configuration
- Deep analysis of C language data storage in memory
- ROS compilation calls the third-party dynamic library (xxx.so)
- Image, CV2 read the conversion and size resize change of numpy array of pictures
猜你喜欢
Export IEEE document format using latex
sublime text的编写程序时的Tab和空格缩进问题
Detailed explanation of dynamic planning
使用latex导出IEEE文献格式
【ROS】usb_ Cam camera calibration
Using pkgbuild:: find in R language_ Rtools check whether rtools is available and use sys The which function checks whether make exists, installs it if not, and binds R and rtools with the writelines
Visual implementation and inspection of visdom
TP-LINK 企业路由器 PPTP 配置
Swagger setting field required is mandatory
Sublime text in CONDA environment plt Show cannot pop up the problem of displaying pictures
随机推荐
项目连接数据库遇到的问题及解决
vb.net 随窗口改变,缩放控件大小以及保持相对位置
LeetCode:221. 最大正方形
LeetCode:394. 字符串解码
PC easy to use essential software (used)
TP-LINK enterprise router PPTP configuration
软件压力测试常见流程有哪些?专业出具软件测试报告公司分享
个人电脑好用必备软件(使用过)
LeetCode:41. Missing first positive number
ESP8266-RTOS物联网开发
Simple use of promise in uniapp
Target detection - pytorch uses mobilenet series (V1, V2, V3) to build yolov4 target detection platform
深度剖析C语言数据在内存中的存储
优秀的软件测试人员,都具备这些能力
C语言双指针——经典题型
sublime text的编写程序时的Tab和空格缩进问题
Image, CV2 read the conversion and size resize change of numpy array of pictures
Tcp/ip protocol
Navicat premium create MySQL create stored procedure
marathon-envs项目环境配置(强化学习模仿参考动作)