OC--Foundation--数组

一、数组是什么?

NSArray是代表元素有序,可重复的一个集合集合中的每个元素都有其对应的索引。

二、NSArray的功能与用法

1.创建NASArray

类方法实例方法
以array开头以init开头
  • array:创建一个不包含任何元素的空NSArray
  • arrayWithContentsOfFile:读取文件内容来创建NSArray
  • initWithContentsOfFile:读取文件内容来创建NSArray
  • arrayWithObject:创建只包含指定元素的NSArray
  • initWithObject:创建只包含指定元素的NSArray
  • arrayWithObjects:创建包含指定N个元素的NSArray
  • initWithObjects:创建包含指定N个元素的NSArray

简化语法:

  • @[元素1,元素2…,]

2.NSArray集合

  • 查询集合元素值NSArray中的索引
  • 根据索引值取出NSArray集合中的元素
  • 对集合中的元素进行整体调用
  • 对NSArray集合进行排序
  • 取出NSArray集合中的部分集合组成新集合
#import<Foundation/Foundation.h>
int main(){
    @autoreleasepool {
    //nil的值并不会存入NSArray集合,只是表示NSArray元素的结束
        NSArray* array=[NSArray arrayWithObjects:@"神奇海螺W",@"神奇海娜",@"神奇海挪",@"娜娜",nil];
        NSLog(@"No.1:%@",[array objectAtIndex:0]);
        NSLog(@"索引第一的元素:%@",[array objectAtIndex:1]);
        NSLog(@"最后一个:%@",[array lastObject]);
        //获取从索引为1的元素开始,以及后边2个元素组成的新集合
        NSArray* arr1=[array objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(1,2)]];
        NSLog(@"%@",arr1);
        //获取元素在集合中的位置
        NSLog(@"神奇海娜的位置为:%ld",[array indexOfObject:@"神奇海娜"]);
        //获取元素在集合指定范围的位置
        NSLog(@"在1-3范围神奇海娜的位置为:%ld",[array indexOfObject:@"神奇海娜"inRange:NSMakeRange(1,1)]);
        //向数组的最后追加另一个数组的所有元素
        array = [array arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:@"娜娜",@"神奇",nil]];
        for(int i=0;i<array.count;i++){
            NSLog(@"%@",[array objectAtIndex:i]);
            //也可写作:NSLog(@"%@",array[i];
        }
        //获取array中索引为2-3的所有元素
        NSArray* arr2=[array subarrayWithRange:NSMakeRange(2,1)];
        //将NSArray集合的元素写入文件
        [arr2 writeToFile:@"myFile.txt"atomically:YES];
    }
}

代码运行结果如下:
在这里插入图片描述
当我们使用arrayByAddingObject:或arrayWithObjects:方法对集合追加元素时,原有的NSArray对象不会发生任何修改,只是返回一个新的NASrray对象

3.NSArray的比较

类的接口部分


#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface User : 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 "0602.h"

@implementation User
-(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);
}
-(BOOL)isEqual:(id)other{
    if(self==other){
        return YES;
    }
    if([other class]==User.class){
        User* target=(User*)other;
        return  [self.name isEqualToString:target.name]&&[self.pass isEqualToString:target.pass];
    }
    return NO;
}
-(NSString*)description{
    return [NSString stringWithFormat:@"<User[name=%@,pass=%@]>",self.name,self.pass];
}
@end

测试:

#import<Foundation/Foundation.h>
#import"0602.h"
int main(int argc,char* argv[]){
    @autoreleasepool {
        NSArray* array=@[
            [[User alloc] initWithName:@"sun" pass:@"123"],
            [[User alloc] initWithName:@"bai" pass:@"345"],
            [[User alloc] initWithName:@"zhu" pass:@"654"],
            [[User alloc] initWithName:@"tang" pass:@"178"],
            [[User alloc] initWithName:@"niu" pass:@"155"]];
        User* newUser=[[User alloc] initWithName:@"zhu" pass:@"654"];
        NSUInteger pos=[array indexOfObject:newUser];
        NSLog(@"newUser的位置为:%ld",pos);
    }
}

代码输出结果如下:
在这里插入图片描述
我们在此创建了一个新的User对象,虽然这个对象和集合中的任意一个对象都不相同,但是仍然可以返回原集合中的索引,因为它和原集合中的对象的name,pass都相同。
类似于C中我们遍历数组找出想要找出的想找的那个元素的下标,当有一个元素和我们输入的元素值相同时,就会返回这个元素的下标,而不需要两个元素完全相同。

三、集合元素的整体调用

1.调用方法

  • 整体调用方法

makeObjectsPerformSelector:传入一个SEL参数,用于指定调用哪个方法
makeObjectsPerformSeletcor:withObject: 第一个SEL参数用于指定调用哪个方法,第二个参数用于调用集合元素的方法时传入参数

  • 隐式遍历方法

enumerateObjectsUsingBlock:遍历集合中的所有元素,并依次使用元素来执行相应代码
enumerateObjectsWithOptions:usingBlock:功能和上边一样,这个可以额外传入一个参数,用于控制遍历的选项,比如反向遍历
enumerateObjectsAtIndexs:options:usingBlock:遍历结婚中指定范围的元素,额外传入的参数可以控制遍历的选项

以上三个方法都需要传入一个代码块参数,该代码块必须带三个参数,第一个参数代表正在遍历集合的元素,第二个参数代表正在遍历元素的索引,第三个参数是用于遍历集合元素的代码块
类的接口和实现部分和之前一样,这里展示测试部分代码:

#import<Foundation/Foundation.h>
#import"0602.h"
int main(int argc,char* argv[]){
    @autoreleasepool {
        NSArray* array=@[
            [[User alloc] initWithName:@"sun" pass:@"123"],
            [[User alloc] initWithName:@"bai" pass:@"345"],
            [[User alloc] initWithName:@"zhu" pass:@"654"],
            [[User alloc] initWithName:@"tang" pass:@"178"],
            [[User alloc] initWithName:@"niu" pass:@"155"]];
        [array makeObjectsPerformSelector:@selector(say:)withObject:@"嘿嘿"];
        NSString* content = @"挪挪";
        [array enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(2, 2)]options:NSEnumerationReverse
                              usingBlock:^(id obj,NSUInteger idx,BOOL *stop){
            NSLog(@"正在处理第%ld个元素:%@",idx,obj);
            [obj say:content];
        }];
    }
}

这里是结果
在这里插入图片描述

Array即可对集合中的所有元素整体调用某个方法,也可以通过NSIndexSet来控制选中部分,程序中执行这些方法时,底层实际上会使用迭代处理调用每个集合的元素,因此这些方法都叫做迭代方法

2.对NSArray进行排序

  • sortedArrayUsingFunction:context:使用排序函数对集合进行排序,排序函数必须返回NSOrderdDescending,NSOrderedAscending,NSOrderedSame,这些枚举值
  • sortedArrayUsingSelector:使用集合自身方法对元素排序,使用的方法必须返回NSOrderdDescending,NSOrderedAscending,NSOrderedSame,这些枚举值。
  • sortedArrayUsingComparator:使用代码块对集合进行排序,代码块必须返回NSOrderdDescending,NSOrderedAscending,NSOrderedSame,这些枚举值。这个方法是sortedaArrayUsingFunction:context:方法的简化版本。

这三种方法用中的枚举值于代表集合元素的大小。三种方法都方法返回一个排序好的NSArray对象

#import<Foundation/Foundation.h>
NSComparisonResult intSort(id num1,id num2, void *context){
    int v1 = [num1 intValue];
    int v2 = [num2 intValue];
    if(v1<v2){
        return NSOrderedAscending;
    }else if (v1 > v2){
        return NSOrderedDescending;
    }else{
        return NSOrderedSame;
    }
}
int main(int argc,char* argv[]){
    @autoreleasepool {
        NSArray* array1 = @[@"magic",@"nuonuo",@"nana",@"hailuo",@"hailuow",@"tang"];
        array1 = [array1 sortedArrayUsingSelector:@selector(compare:)];
        NSLog(@"%@",array1);
        NSArray* array2=@[[NSNumber numberWithInt:20],
        [NSNumber numberWithInt:12],
        [NSNumber numberWithInt:-8],
        [NSNumber numberWithInt:50],
        [NSNumber numberWithInt:19],
        ];
        array2 = [array2 sortedArrayUsingFunction:intSort context:nil];
        NSLog(@"%@",array2);
        NSArray* array3=[array2 sortedArrayUsingComparator:
                         ^(id obj1,id obj2){
        if([obj1 intValue]>[obj2 intValue]){
            return NSOrderedDescending;
        }if([obj1 intValue]<[obj2 intValue]){
            return NSOrderedAscending;
        }
        return NSOrderedSame;
        }];
        NSLog(@"%@",array3);
}
}

测试结果如下:
在这里插入图片描述

需要注意:如果元素中有特殊符号,打印出来的值会有双引号
在这里插入图片描述

第一种排序方法是使用集合的compare:方法进行排序。这种排序方法是根据字符对应的编码来实现的
后两种方法是通过调用函数或者代码块来比较大小

自然排序:指集元素本身可比较大小,而且直接利用集合元素比较大小的方法进行排序的方法。

定制排序:通过函数或者代码块来指定自定义的比较规则的方法

四、枚举器遍历NSArray

对于NSArray对象,除了可用集合的索引来遍历集合元素外,还可以调用NSArray对象的方法来返回枚举器。

objectEnumerator:返回NSArray集合的顺序枚举器
reverseObjectEnumerator:返回NSArray集合的逆序枚举器

这两种方法都返回一个NSEnumerator枚举器包含如下两个方法:

allObjects:获取被枚举集合中的所有元素
nextObject:获取被枚举集合中的下一个元素

测试:

#import<Foundation/Foundation.h>
int main(int argc,char* argv[]){
    @autoreleasepool {
        NSArray* array = [NSArray arrayWithContentsOfFile:@"my.File.txt"];
        NSEnumerator* en = [array objectEnumerator];
        id object;
        while(object = [en nextObject]){
            NSLog(@"%@",object);
            
        }
        NSLog(@"-------下面逆序遍历------");
        en = [array reverseObjectEnumerator];
        while(object = [en nextObject]){
            NSLog(@"%@",object);
        }
}
}

结果如下:
在这里插入图片描述
在这里插入图片描述

五、快速枚举

OC还提供了快速枚举的方法来遍历集合(NSArray,NSSet,NSDictionary),使用快速枚举时,无需获得集合长度。也无需根据索引来访问集合元素。

如果使用快速枚举来遍历NSDictionary对象,快速枚举中的计数器将依次代表NSDictionary中的每个key的值。

#import<Foundation/Foundation.h>
int main(int argc,char* argv[]){
    @autoreleasepool {
        NSArray* array = [NSArray arrayWithContentsOfFile:@"my.File.txt"];
        for(id object in array){
            NSLog(@"%@",object);
        }
    }
}

快速枚举的本质是一个for-each循环,for-each循环无需循环条件,也无需循环迭代语句。for-each循环自动迭代数组的每个元素,当每个元素都被迭代一次后,foe-each循环自动结束

六、可变数组

1.NSMutableArray

NSArray代表集合元素不可变的集合,一旦NSArray创建成功,程序就不能向集合中添加替换或删除元素
NSArray只是保存对象的指针,指针变量中的地址不能改变,但是地址指向的对象可以被改变。

NSMutableArray是NSArray的一个子类。
它代表一个集合元素可变的集合,程序可以向集合中添加删除修改元素。
NSMutableArray底层采用传统数组来容纳集合元素,因此,创建NSMutalbeArray时可以通过参数指定底层数组的初始容量。

在这里插入图片描述

NSMutableArray同样提供了sortUsingSelector:,sortUSingComparator:,sortUsingFunction:context:这三个排序方法,不同的是这三个方法返回一个新的排好序的NSArray对象,而NSMutableArray排序方法是对集合本身排序

#import<Foundation/Foundation.h>
//次函数用于将NSArray集合转换成字符串,这样方便调试时看到NSArray集合中的元素
NSString* NSCollectionToString(NSArray* array){
    NSMutableString* result = [NSMutableString stringWithString:@"["];
    for(id obj in array){
        [result appendString:[obj description]];
        [result appendString:@","];
    }
    NSUInteger len = [result length];
    [result deleteCharactersInRange:NSMakeRange(len-2, 2)];
    [result appendString:@"]"];
    return result;
}
int main(int argc,char* argv[]){
    @autoreleasepool {
        NSMutableArray* array = [NSMutableArray arrayWithContentsOfFile:@"myFile.txt"];
        [array addObject:@"疯狂iOS讲义"];
        NSLog(@"最后追加一个元素后:%@",NSCollectionToString(array));
        [array addObjectsFromArray:[NSArray arrayWithObjects:@"张飞",@"关羽",nil]];
        NSLog(@"最后追加两个元素后:%@",NSCollectionToString(array));
        [array insertObject:@"疯狂Ajax讲义" atIndex:2];
        NSLog(@"在索引为2处插入一个元素后:%@",NSCollectionToString(array));
        [array insertObjects:[NSArray arrayWithObjects:@"武松",@"林冲",nil]
                   atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(3, 2)]];
        NSLog(@"插入多个元素后:%@",NSCollectionToString(array));
        [array removeLastObject];
        NSLog(@"删除最后一个元素后:%@",NSCollectionToString(array));
        [array removeObjectAtIndex:5];
        NSLog(@"删除索引为5的元素后:%@",NSCollectionToString(array));
        [array removeObjectsInRange:NSMakeRange(2,3)];
        NSLog(@"删除索引为2~4的元素后:%@",NSCollectionToString(array));
        [array replaceObjectAtIndex:2 withObject:@"嘿嘿"];
        NSLog(@"替换索引为2处的元素后:%@",NSCollectionToString(array));
    }
}

在这里插入图片描述

2.NSArray的KVC和KVO

  • KVC编码

setValue:forKet:将NSArray集合中的所有元素指定key对应属性或实例变量设置为value
valueForKey:返回NSArray集合中的所有元素指定的key组成的NSArray对象

  • KVO编码
addObserver:forKeyPath:options:context为集合中的所有元素添加KVO监听器
removeObserver:forKeyPath:为集合中所有元素删除KV O监听器
addObserver:toObjectsAtIndexes:forKeyPath:options:contex:为集合中指定索引处的元素添加KVO监听器
removeObserver:fromObjectsAtIndexes:forKeyPath:为集合中指定索引处的元素删除KVO监听器

类的接口和实现部分和之前一样,这里展示测试部分代码:

#import<Foundation/Foundation.h>
#import"0602.h"
NSString* NSCollectionToString(NSArray* array){
    NSMutableString* result = [NSMutableString stringWithString:@"["];
    for(id obj in array){
        [result appendString:[obj 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 = @[
        [[User alloc]initWithName:@"sun" pass:@"123"],
        [[User alloc]initWithName:@"bai" pass:@"345"],
        [[User alloc]initWithName:@"zhu" pass:@"654"],
        [[User alloc]initWithName:@"tang" pass:@"178"],
        [[User alloc]initWithName:@"niu" pass:@"155"]];
        //将name属性取出来
        id newArr = [array valueForKey:@"name"];
        NSLog(@"%@",NSCollectionToString(newArr));
        //将所有的name属性改为新值
        [array setValue:@"新名字"forKey:@"name"];
        NSLog(@"%@",NSCollectionToString(array));
    }
}

运行结果如下:在这里插入图片描述

  • 9
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山河丘壑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值