Collection 类的实例用于保存指向其他对象的指针。Collection 类包括:
NSArray 、NSMutableArray
NSSet 、NSMutableSet
-
NSSet
对象所包含的“内容”是无序的。而且在一个NSSet
对象中,某个特定的对象只能出现一次(唯一性)。 -
NSSet
对象的最大用处是检查某个对象是否存在,NSSet
完成此类任务的速度比数组快得多。
NSSet 与 NSArray 的区别:
-
NSSet
和数组一样,是个数据容器。 - 数组是有序的,
NSSet
是无序的。 - 数组可以容纳重复对象,
NSSet
不能。 - 数组是有下标的,
NSSet
没有下标。
NSSet 的创建
// alloc 创建
NSSet *set1 = [[NSSet alloc] initWithObjects:@“张三”,@“李四”, nil];
// 类方法创建
NSSet *set2 = [NSSet setWithObjects:s@“张三”,@“李四”,nil];
其他集合常用创建方法
// 创建一个新的集合1,集合2有两个对象(a和b)
NSSet *set1 = [NSSet setWithObjects:@"a", nil];
NSSet *set2 = [set1 setByAddingObject:@"b"];
// 通过已有集合7和集合8,创建一个新的集合9
NSSet *set7 = [NSSet setWithObjects:@"a", nil];
NSSet *set8 = [NSSet setWithObjects:@"z", nil];
NSSet *set9 = [set7 setByAddingObjectsFromSet:set8];
// 通过已有的集合10和数组对象,创建一个新的集合11
NSArray *array = [NSArray arrayWithObjects:@"a", @"b", @"c", nil];
NSSet *set10 = [NSSet setWithObjects:@"z", nil];
NSSet *set11 = [set10 setByAddingObjectsFromArray:array];
NSSet 与 NSArray 相互转换
// NSSet -> NSArray
NSArray *array = [set1 allObjects];
// NSArray --> NSSet
// 如果同一个对象在数组中出现多次,那么它只会添加一次到给定的集合。 每个对象在被添加到集合中时只会收到一次保留消息。
NSSet *set3 = [NSSet setWithArray:array];
返回集合元素的个数
NSUInteger count = [set1 count];
从容器中随机取出一个元素
NSString *s = [set1 anyObject];
判断对象是否在 NSSet 中已经存在
- (BOOL)containsObject:(ObjectType)anObject;
示例:
BOOL isContain = [set1 containsObject:@"李四"];
-
NSSet
对象中的对象是无序的,所以不能通过索引来访问,只能向NSSet
对象查询某一个对象是否存在。 - 当
NSSet
收到- (BOOL)containsObject:(ObjectType)anObject;
消息时,会在其包含的对象中查找和 anObject 相等的对象 (内容相同,地址可能不同,也就是说可能 【指针指向的内容是相等的】,但是他们两个【未必是同一块地址】,返回 YES)。 - 因此,相同的变量(指针指向同一块内存地址)一定是相等的,而相等的变量不一定是相同的。
NSMutableSet
NSMutableSet
是可变集合,它继承自 NSSet
。
常用方法
// 创建一个空的集合
NSMutableSet *set1 = [NSMutableSet set];
NSMutableSet *set2 = [NSMutableSet setWithObjects:@"1", @"2", nil];
// 集合2“减去”集合3中的元素
[set2 minusSet:set3];
// 集合2与集合3中元素的交集
[set2 intersectSet:set3];
// 集合2与集合3中的元素的并集;
[set2 unionSet:set3];
// 将空集合1设置为集合3中的内容
[set1 setSet:set3];
// 根据数组的内容删除集合中的对象
[set2 addObjectsFromArray:array];
[set2 removeObject:@"1"];
[set2 removeAllObjects];
NSDictionary
- 字典是由 键—值对组成的数据容器, 通过 key (键,通常是字符串),查找对应 value (值,可以是任意类型的对象)。
- 字典中的 键—值对是无序的。
- 字典对象中的键都是独一无二的,如果想要在现存的键后再添加第二个对象,第一个键—值对就会被替换掉。
- 字典中的key可以是任意类型,一般使用字符串作为一个元素的 key。
-
NSDictionary
是不可变字典。
字典的创建
NSArray *array1 = @[@"zhang3",@"zhangfei"];
NSArray *array2 = @[@"li4",@"liming"];
/*
字典的结构
第一个元素:key:@"zhang" value:array1
第二个元素:key:@"li" value:array2
...
*/
// 1.alloc方法创建
NSDictionary *dic1 = [[NSDictionary alloc] initWithObjectsAndKeys:
array1,@"zhang",
array2,@"li", nil];
// xcode4.4以后对字典的创建和访问,语法上做了优化。
NSDictionary *dic11 = @{
@"zhang":array1,
@"li":array2
};
// 2.类方法创建字典
NSDictionary *dic2 = [NSDictionary dictionaryWithObjectsAndKeys:
array1,@"zhang",
array2,@"li", nil];
返回字典元素个数
NSUInteger count = [dic1 count];
通过 key 获取对应的 value
NSArray *array3 = [dic1 objectForKey:@"zhang"];
// 简便写法
NSArray *array3 = dic1[@"zhang"];
取得所有的 keys
NSArray *allkeys = [dic1 allKeys];
取得所有的 Values
NSArray *allvalue = [dic1 allValues]; //同下get方法
NSArray *allvalue2 = dic1.allValues;
遍历字典
// 1.普通遍历
NSArray *keys = [dic1 allKeys]; //NSDictionary -> NSArray
for (int i =0;i <keys.count;i++) {
NSString *key = keys[i]; //通过下标获取对象key
NSArray *names =[dic1 objectForKey:key]; //通过key获取对应的value
NSLog(@"key=%@,value=%@",key,names);
}
// 2.快速遍历
for (NSString *key in dic1) {
NSArray *names = [dic1 objectForKey:key];
NSLog(@"key=%@,value=%@",key,names);
}
删除服务器返回的 value 为 NULL 的情况
#import <Foundation/Foundation.h>
/**
范畴
*/
@interface NSDictionary (MyCustomize)
/**
填充value为空造成的crash
@return 修改后的NSDictionary
*/
- (NSDictionary *)deleteAllNULLValue;
@end
#import "NSDictionary+MyCustomize.h"
/**
自定义范畴类
*/
@implementation NSDictionary (MyCustomize)
- (NSDictionary *)deleteAllNULLValue {
NSMutableDictionary *mutableDic = [[NSMutableDictionary alloc] init];
for (NSString *keyStr in self.allKeys) {
if ([[self objectForKey:keyStr] isEqual:[NSNull null]]) {
[mutableDic setObject:@"null" forKey:keyStr];
HQLog(@"changed!");
}
else{
[mutableDic setObject:[self objectForKey:keyStr] forKey:keyStr];
HQLog(@"no null");
}
}
return mutableDic;
}
@end
NSMutableDictionary
NSMutableDictionary
是可变字典,字典中的存储是可以修改的。NSMutableDictionary
继承于 NSDictionary
。
创建可变字典
// 1.alloc 方法创建
NSArray *array = [NSArray arrayWithObjects:@"张三",@"李四",@"王五", nil];
NSMutableDictionary *mdic = [[NSMutableDictionary alloc]
initWithObjectsAndKeys:array,@"names", nil];
NSMutableDictionary *mdic1 = [[NSMutableDictionary alloc] init];
[mdic1 setObject:array forKey:@"names"]; // 添加元素
NSMutableDictionary *mdic2 = [[NSMutableDictionary alloc] initWithCapacity:3];
添加元素
// 如果key是重复的,会将之前的value覆盖掉
[mdic setObject:@"value" forKey:@"zhang"];
// 将另外一个字典所有的元素添加到mdic中
[mdic addEntriesFromDictionary:<#(nonnull NSDictionary *)#>];
删除元素
// 1>根据Key删除元素
[mdic removeObjectForKey:@"names"];
// 2>根据多个key删除多个元素
[mdic removeObjectForKey:@[@"zhang",@"li"]];
// 3>删除所有元素
[mdic removeAllObjects];
数组排序
过滤
- 匹配字符串:正则表达式
// 正则表达式:验证码
- (BOOL) validateYzm:(NSString *)yzm {
NSString *regex = @"^\\d{4}$";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];
return [predicate evaluateWithObject:yzm];
}
- 过滤 collection
-
NSMutableArray
有一个名为- filterUsingPredicate:
的方法,通过该方法可以很方便地剔除所有不能“满足”传入的NSPredicate
对象的对象。 -
NSArray
有一个名为filteredArrayUsingPredicate:
的方法,可以创建一个新的数组,包含所有能够满足传入的NSPredicate
对象的对象。
// 要收回拥有物品总价值高于75美元的员工的物品
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"holder.valueOfAssets > 70"];
NSArray *toBeReclaimed = [allAssets filteredArrayUsingPredicate:predicate];
NSLog(@"toBeReclaimed:%@",toBeReclaimed);
NSSet
也有一个方法可以来做过滤,代码如下:
- (NSSet<ObjectType> *)filteredSetUsingPredicate:(NSPredicate *)predicate;
NSMutableSet
也有一个这样的方法,如下:
- (void)filterUsingPredicate:(NSPredicate *)predicate;
NSNull
collection 对象不能保存 nil
。如果要将“空洞”加入集合对象中,可以使用 NSNull
类。NSNull
类只有一个实例,代表“空”。
示例代码如下:
NSMutableArray *hotel = [[NSMutableArray alloc] init];
// 底楼大厅
[hotel addObject:@"lobby"];
// 二楼泳池
[hotel addObject:@"pool"];
// 三楼未建,为空!!!
[hotel addObject:[NSNull null]];
// 四楼卧室
[hotel addObject:@"bedrooms"];
NSIndexSet
这个类用于存储有序的索引到某种数据结构,比如数组。例如,使用这个类可以生成一份数组对象的索引号清单,这些对象满足指定的查询条件。
- (NSUInteger)indexOfObjectPassingTest:
示例代码:
NSArray *array = @[@1, @2, @3, @4, @5];
// 遍历数组,取出满足条件的数组索引
NSUInteger result = [array indexOfObjectPassingTest:^BOOL(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([(NSNumber *)obj intValue] % 2 == 0) {
return YES;
}else {
return NO;
}
}];
// 如果找到一个匹配,则查看并打印此项
if (result != NSNotFound) {
NSLog(@"%@",array[result]);
}
// >输出:2
结论:只可以返回一个索引。
- (NSIndexSet *)indexesOfObjectsPassingTest:
示例代码:
NSArray *array = @[@1, @2, @3, @4, @5];
// 遍历数组,取出满足条件数组的所有索引
NSIndexSet *result = [array indexesOfObjectsPassingTest:^BOOL(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([(NSNumber *)obj intValue] % 2 == 0) {
return YES;
}else {
return NO;
}
}];
// 遍历 NSIndexSet
[result enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) {
NSLog(@"%@",array[idx]);
}];
// Output:
// 2017-11-17 10:20:13.694049+0800 Test[39023:9364337] 2
// 2017-11-17 10:20:13.694204+0800 Test[39023:9364337] 4
NSIndexSet 常用方法
// 创建一个空的索引集合
+ (instancetype)indexSet;
// 给定索引创建索引集合
+ (instancetype)indexSetWithIndex:(NSUInteger)value;
// 给定索引范围创建索引集合
+ (instancetype)indexSetWithIndexesInRange:(NSRange)range;
- (instancetype)initWithIndexesInRange:(NSRange)range NS_DESIGNATED_INITIALIZER;
// 根据另一个索引集合创建索引集合
- (instancetype)initWithIndexSet:(NSIndexSet *)indexSet NS_DESIGNATED_INITIALIZER;
// 给定索引值初始化索引集合
- (instancetype)initWithIndex:(NSUInteger)value;
// 判断两个索引集合是否相等
- (BOOL)isEqualToIndexSet:(NSIndexSet *)indexSet;
// 是否包含指定的索引
- (BOOL)containsIndex:(NSUInteger)value;
// 是否包含索引范围
- (BOOL)containsIndexesInRange:(NSRange)range;
// 遍历索引集合方法
- (void)enumerateIndexesUsingBlock:(void (NS_NOESCAPE ^)(NSUInteger idx, BOOL *stop))block API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
- (void)enumerateIndexesWithOptions:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(NSUInteger idx, BOOL *stop))block API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
- (void)enumerateIndexesInRange:(NSRange)range options:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(NSUInteger idx, BOOL *stop))block API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
// ...