[Foundation]框架--数组和集合

文章详细介绍了NSArray的创建、常用方法,如获取元素、索引操作、追加元素、排序等,并通过示例代码展示了快速枚举和可变数组NSMutableArray的使用。接着,文章讨论了NSSet的特点和用法,包括添加元素、集合运算和成员检测等操作,同时提到了可变集合NSMutableSet的相关功能。
摘要由CSDN通过智能技术生成

一. 数组
NSArray代表元素有序,可重复的一个集合,集合都有其对应的顺序索引。
1. NSArray的功能与用法
NSArray分别提供类方法与类实例方法创建NSArray,两种创建方法需要传入参数基本相似,类方法一array开头,而实例方法则以init开头。下面是几类常见的方法:
在这里插入图片描述
还可以使用简化语法来创建NSArray对象:

@[元素1,元素2,元素3......]

参考NSArray类的文档,可以看到NSArray集合的方法大致包括如下几类。
在这里插入图片描述
下类代码展示了NSArray集合的常规用法。

#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSArray* array = [NSArray arrayWithObjects:@"疯狂iOS讲义", @"疯狂Android讲义", @"疯狂Ajax讲义", @"疯狂XML讲义", @"疯狂Swift讲义", nil];
        NSLog(@":第一个元素:%@", [array objectAtIndex: 0]);
        NSLog(@":第二个元素:%@", [array objectAtIndex: 1]);
        NSLog(@":第三个元素:%@", [array objectAtIndex: 2]);
        //获取索引为2的元素开始,以及后面3个元素组成的新集合
        NSArray* arr1 = [array objectsAtIndexes: [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(2, 3)]];
        NSLog(@"%@", arr1);
        //获取元素在集合中的位置
        NSLog(@"疯狂Android讲义的位置:%ld",[array indexOfObject:@"疯狂Android讲义"]);
        //获取元素在集合指定范围中的位置
        NSLog(@"在2~5范围疯狂Android讲义的位置:%ld", [array indexOfObject:@"疯狂Android讲义" inRange:NSMakeRange(2, 3)]);
        //向数组的最后追加一个元素
        //原来的NSArray没有改变,只是将新返回的NSArray赋给array;
        array = [array arrayByAddingObject:@"孙悟空"];
        //向array数组最后追加另一个数组的所有元素
        //原来的NSArray没有改变,只是将新返回的NSArray赋给array;
        array = [array arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:@"宝玉", @"黛玉", nil]];
        for (int i = 0;i < array.count;i++) {
            //NSLog(@"%@", [array objectAtIndex:i]);
            //上述代码可以简化为下面的形式
            NSLog(@"%@", array[i]);
        }
        NSArray* arr2 = [array subarrayWithRange:NSMakeRange(5, 3)];
        NSLog(@"%@",arr2);
    }
    return 0;
}

代码运行如下:
在这里插入图片描述
上述程序试图返回“疯狂Android讲义”字符串对象在NSArray集合中NSRange(2,3)范围,实际上该位置并没有包含该字符串对象,因此程序返回9223372036854775807,这是常量NSNotFound的值。
程序采用两种方法向NSArray集合后面追加元素:

arrayByAddingObject: 方法追加单个元素;
arrayWithObjects: 方法追加另一个数组的全部元素;

不论是用哪一种方法,对于原NSArray对象都不会产生任何修改,程序只是返回一个新的NSArray对象。
在这里插入图片描述
接下来展示NSArray的比较机制:
接口部分:

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface FKUser : NSObject
@property (nonatomic, copy) NSString* name;
@property (nonatomic, copy) NSString* pass;
- (id) initWithName: (NSString* ) name pass: (NSString* ) pass;
- (void) say: (NSString* ) content;
@end

NS_ASSUME_NONNULL_END

实现部分:

#import "FKUser.h"
@implementation FKUser

- (id)initWithName:(nonnull NSString *)name pass:(nonnull NSString *)pass {
    if (self == [super init]) {
        self.name = name;
        self.pass = pass;
    }
    return self;
}
- (void)say:(nonnull NSString *)content {
    NSLog(@"%@说:%@", self.name, content);
}
//重写isEqual:方法,重写方法的标准是如果两个FKUser的name, pass相等,即可认为他们相等。
- (BOOL) isEqual:(id) other {
    if (self == other) {
        return YES;
    }
    if ([other class] == FKUser.class) {
        FKUser* target = (FKUser* ) other;
        return [self.name isEqual:target.name] &&[self.pass isEqual:target.pass];
    }
    return NO;
}
//重写description方法,可以直接看到FKUser对象的状态
- (NSString*) description {
    return [NSString stringWithFormat:@"<FKUser[name = %@, pass = %@]>", self.name, self.pass];
}
@end

主代码部分:

#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:@"lai" pass:@"124"], 
            [[FKUser alloc] initWithName:@"li" pass:@"125"], 
            [[FKUser alloc] initWithName:@"gao" pass:@"126"],
            [[FKUser alloc] initWithName:@"zhu" pass:@"127"] ];
        FKUser* newUser = [[FKUser alloc] initWithName:@"li" pass:@"125"];
        //查找指定新的FKUser对象在集合中的索引
        NSUInteger pos = [array indexOfObject:newUser];
        //打印出newUser的信息
        NSLog(@"%@", [newUser description]);
        NSLog(@"newUser的位置为%ld", pos);
    }
    return 0;
}

代码运行结果如下:
在这里插入图片描述
2. 对集合元素整体调用方法
NSArray允许对集合中所有元素或者部分元素整体进行调用方法,如果只是简单地调用集合元素的方法,可以通过NSArray的如下方法来实现:
在这里插入图片描述
如果希望对集合中的所有元素进行隐式遍历,并使用集合元素来执行某段代码,则可通过NSArray的如下方法:
在这里插入图片描述
在这里插入图片描述
下面来看代码:

#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:@"lai" pass:@"124"], [[FKUser alloc] initWithName:@"li" pass:@"125"], [[FKUser alloc] initWithName:@"gao" pass:@"126"],[[FKUser alloc] initWithName:@"zhu" pass:@"127"] ];
        //对集合元素整体调用方法
        [array makeObjectsPerformSelector:@selector(say:) withObject:@"下午好,iOS真强大"];
        NSString* content = @"疯狂iOS讲义";
        //迭代计划内指定范围内的元素,并使用该元素执行块代码
        [array enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(2, 2)] options:NSEnumerationReverse
         //代码块的第一个参数代表正在遍历的集合元素
         //代码块的第二个参数代表正在便利的集合元素的索引
         //代码块的第三个参数用于控制是否停止遍历,将该参数设置为NO即可停止遍历
            usingBlock: ^(id obj, NSUInteger idx, BOOL *stop) {
            NSLog(@"正在处理第%ld个元素: %@", idx, obj);
            [obj say: content];
        }];
    }
    return 0;
}

在这里插入图片描述
代码执行结果如下:
在这里插入图片描述
在这里插入图片描述
3. 对NSArray进行排序
NSArray提供了大量方法对集合元素进行排序,这些排序方法都以sorted开头,下面是几个比较常用的:
在这里插入图片描述
如下列代码所示对集合进行排序:

#import <Foundation/Foundation.h>
//定义比较函数,根据两个对象的inValue进行比较
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;
    }
}
#import "FKUser.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //初始化一个元素的NSString的NSArray对象
        NSArray* array1 = @[@"Objective-C", @"C", @"C++", @"Ruby", @"Perl", @"Swift"];
        //使用集合元素的copmare:方法进行排序
        array1 = [array1 sortedArrayUsingSelector:@selector(compare:)];
        NSLog(@"%@", array1);
        //初始化一个元素为NSNumber的NSArray对象
        NSArray* array2 = @[[NSNumber numberWithInt:20],
                            [NSNumber numberWithInt:12],
                            [NSNumber numberWithInt:-8],
                            [NSNumber numberWithInt:50],
                            [NSNumber numberWithInt:19] ];
        //使用inSort函数进行排序
        array2 = [array2 sortedArrayUsingFunction: intSort context: nil];
        NSLog(@"%@", array2);
        //使用代码块对集合元素进行排序
        NSArray* array3 = [array2 sortedArrayUsingComparator:^(id obj1, id obj2) {
            //该代码就是根据集合元素inValue进行比较
            if ([obj1 intValue] > [obj2 intValue]) {
                return NSOrderedDescending;
            }
            if ([obj1 intValue] < [obj2 intValue]) {
                return NSOrderedAscending;
            }
            return NSOrderedSame;
            }];
        NSLog(@"%@", array3);
    }
    return 0;
}

代码运行结果如下:
在这里插入图片描述
4. 使用枚举器遍历NSArray集合元素
对于NSArray对象,除了可以更具集合的索引来遍历集合元素之外,还可以调用NSArray对象的如下两个方法来返回枚举器。
在这里插入图片描述
上面两个方法都返回一个NSEnumerator枚举器,。该枚举器之包含下面两个方法:
在这里插入图片描述
使用下面代码进行示例:

#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSArray* array = [NSArray arrayWithObjects:@"孙悟空", @"赖晨煜", @"黛玉", @"宝玉", nil];
        //获取NSArray的顺序枚举器
        NSEnumerator* en = [array objectEnumerator];
        id object;
        while (object = [en nextObject]) {
            NSLog(@"%@",object);
        }
        NSLog(@"----下面逆序遍历----");
        //获取NSArray的逆序枚举器
        en = [array reverseObjectEnumerator];
        while (object = [en nextObject]) {
            NSLog(@"%@",object);
        }
    }
    return 0;
}

代码运行结果如下:
在这里插入图片描述
5. 快速枚举(for … in)
Objective-C还提供了一种快速枚举的方法来遍历集合,使用快速枚举遍历集合元素时,无需获得集合的长度,也无需根据索引来访问集合元素,即可快速枚举自动遍历集合的每一个元素。

for (type variableName in collection) {	
	//variableName 自动迭代访问每个元素
}

下面是代码示例:

#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSArray* array = [NSArray arrayWithObjects:@"孙悟空", @"赖晨煜", @"黛玉", @"宝玉", nil];
        for (id object in array) {
            NSLog(@"%@", object);
        }
    }
    return 0;
}

代码运行结果如下:
在这里插入图片描述
6. 可变数组(NSMutableArray)
NSArray是不可变的集合,一旦创建成功,程序不能向集合中添加新的元素,不能删除已有的元素,也不能替换集合元素。
在这里插入图片描述
NSMutableArray代表集合元素可变的集合,而NSMutableArray底层采用传统数组来容纳集合元素,因此创建NSMutableArray是可以通过参数指定底层数组的初始容量。
在这里插入图片描述
在这里插入图片描述
下面代码展示了如何改变NSMutableArray集合中的元素:

#import <Foundation/Foundation.h>
//定义一个函数,该函数用于把NSArray集合转换为字符串
NSString* NSCollectionToString (NSArray* array) {
    NSMutableString* result = [NSMutableString stringWithString:@"["];
    for (id object in array) {
        [result appendString: [object description]];
        [result appendString: @", "];
    }
    NSUInteger len = [result length]; //获取集合长度
    //去掉字符串最后两个字符
    [result deleteCharactersInRange:NSMakeRange(len - 2, 2)];
    [result appendString:@"]"];
    return result;
}
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSMutableArray* array = [NSMutableArray arrayWithObjects:@"孙悟空", @"赖晨煜", @"黛玉", @"宝玉", nil];
        //向集合最后添加一个元素
        [array addObject:@"疯狂iOS讲义"];
        NSLog(@"最后追加一个元素后:%@", NSCollectionToString(array));
        //使用NSArray将集合尾部添加多个元素
        [array addObjectsFromArray:[NSArray arrayWithObjects:@"穷奇", @"浑沌", @"貔貅", nil]];
        NSLog(@"最后追加三个元素后:%@", NSCollectionToString(array));
        //向集合的指定位置插入一个元素
        [array insertObject:@"疯狂Ajax讲义" atIndex:2];
        NSLog(@"在索引为2出插入一个元素后:%@", NSCollectionToString(array));
        //使用NSArray向集合指定位置插入多个元素
        [array insertObjects:[NSArray arrayWithObjects: @"成龙", @"苏武",@"共工", nil] atIndexes:[NSIndexSet indexSetWithIndexesInRange: NSMakeRange(2, 3)]];
        NSLog(@"插入多个元素后:%@", NSCollectionToString(array));
        //删除集合最后一个元素
        [array removeLastObject];
        NSLog(@"删除最后一个元素后:%@", NSCollectionToString(array));
        //删除集合中指定索引处的元素后
        [array removeObjectAtIndex: 5];
        NSLog(@"删除索引为5的元素后:%@", NSCollectionToString(array));
        //删除集合中索引为2~4处的元素
        [array removeObjectsInRange:NSMakeRange(2, 3)];
        NSLog(@"删除索引为2~4处的元素后:%@", NSCollectionToString(array));
        //替换索引为2的元素
        [array replaceObjectAtIndex:2 withObject:@"疯狂Android讲义"];
        NSLog(@"替换索引为2处的元素后:%@", NSCollectionToString(array));
        
    }
    return 0;
}

在这里插入图片描述
二.集合
NSSet是一个广泛使用的集合,但是NSSet集合中不允许包含相同的元素,如果把相同的元素放入同一个集合中,则只会保留一个元素。
NSSet不能保证元素的添加顺序,顺序有可能发生改变,与NSArray相比,NSSet最大的区别是元素没有索引,不能根据元素索引来操作元素。
1. NSSet的功能与用法
获取NSSet对象后,接下来可以调用NSSet的方法来访问元素集合:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下面代码示范了NSSet集合的基本用法:

#import <Foundation/Foundation.h>
//把集合转换为字符串
NSString* NSCollectionToString (id array) {
    NSMutableString* result = [NSMutableString stringWithString:@"["];
    for (id object in array) {
        [result appendString: [object description]];
        [result appendString: @", "];
    }
    NSUInteger len = [result length]; //获取集合长度
    //去掉字符串最后两个字符
    [result deleteCharactersInRange:NSMakeRange(len - 2, 2)];
    [result appendString:@"]"];
    return result;
}
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //使用4个元素初始化NSSet集合
        //故意传入两个相同的元素,NSSet集合只会保留一个
        NSSet* set1 = [NSSet setWithObjects:@"疯狂iOS讲义", @"疯狂Android讲义", @"疯狂Ajax讲义", @"疯狂iOS讲义", nil];
        //程序输出set1集合中的元素个数为3
        NSLog(@"set1集合中元素个数为:%ld", [set1 count]);
        NSLog(@"s1集合:%@", NSCollectionToString(set1));
        NSSet* set2 = [NSSet setWithObjects:@"孙悟空", @"疯狂Android讲义", @"猪八戒", nil];
        NSLog(@"s2集合:%@", NSCollectionToString(set2));
        //把一个元素追加到set1后面,然后把新生成的集合赋值给set1
        set1 = [set1 setByAddingObject: @"Struts 2.1权威指南"];
        NSLog(@"添加一个元素后:%@", NSCollectionToString(set1));
        //使用NSSet集合想集合set1中添加多个元素,相当于两个集合的交集
        NSSet* s = [set1 setByAddingObjectsFromSet: set2];
        NSLog(@"set1集合与set2集合的并集:%@", NSCollectionToString(s));
        //计算两个集合是否有交集
        BOOL b = [set1 intersectsSet:set2];
        //将输出代表yes的1
        NSLog(@"set1和set2是否有交集:%d", b);
        //判断set1是否包含set2
        BOOL bo = [set1 isSubsetOfSet: set2];
        //将输出代表no的0
        NSLog(@"set2是否是set1的子集:%d", bo);
        //判断集合是否包含指定元素
        BOOL bb = [set1 containsObject: @"疯狂Android讲义"];
        //将输出代表yes的1
        NSLog(@"set1中是否包含疯狂Android讲义: %hhd", bb);
        //下面两行代码将会取出相同的的元素但是取出那个元素不确定
        NSLog(@"set1取出一个元素:%@", [set1 anyObject]);
        NSLog(@"set1取出一个元素:%@", [set1 anyObject]);
        //使用代码块对集合元素进行过滤
        NSSet* filteredSet = [set1 objectsPassingTest: ^(id obj, BOOL *stop) {
            return (BOOL) ([obj length] > 8);
        }];
        NSLog(@"set1中元素的长度大于8的集合元素有:%@", NSCollectionToString(filteredSet));
    }
    return 0;
}

代码运行结果如下:
在这里插入图片描述
2.NSMutableSet的功能与用法
NSMutableSet继承了NSSSet,它代表了一个集合元素可变的NSSet集合,并且NSMutableSet在NSSet的基础上还增加了对于集合交集,并集,差集的方法。
在这里插入图片描述
下面代码示范了NSMutableSet集合的用法:

#import <Foundation/Foundation.h>
//把集合转换为字符串
NSString* NSCollectionToString (id array) {
    NSMutableString* result = [NSMutableString stringWithString:@"["];
    for (id object in array) {
        [result appendString: [object description]];
        [result appendString: @", "];
    }
    NSUInteger len = [result length]; //获取集合长度
    //去掉字符串最后两个字符
    [result deleteCharactersInRange:NSMakeRange(len - 2, 2)];
    [result appendString:@"]"];
    return result;
}
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //创建一个初始化容量为10的集合
        NSMutableSet* set = [NSMutableSet setWithCapacity:10];
        [set addObject:@"赖晨煜"];
        NSLog(@"添加一个元素后:%@", NSCollectionToString(set));
        [set addObject: [NSArray arrayWithObjects:@"孙悟空", @"猪八戒", @"白龙马", nil]];
        NSLog(@"添加了3个元素之后:%@", NSCollectionToString(set));
        [set removeObject:@"猪八戒"];
        NSLog(@"删除了1个元素之后:%@", NSCollectionToString(set));
        //在此创建一个一个NSSet集合
        NSSet* set2 = [NSSet setWithObjects:@"猪八戒", @"疯狂iOS讲义", nil];
        //计算两个集合的并集
        [set unionSet:set2];
        NSLog(@"%@", NSCollectionToString(set));
        //计算两个集合的差集
        [set minusSet:set2];
        NSLog(@"%@", NSCollectionToString(set));
        //计算两个集合的交集
        [set intersectSet:set2];
        NSLog(@"%@", NSCollectionToString(set));
        //用set2的值覆盖set的值
        [set setSet:set2];
        NSLog(@"%@",NSCollectionToString(set));
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值