《Objective-C 編程》24.Collection 集合類

Collection 類的實(shí)例用于保存指向其他對(duì)象的指針檩帐。Collection 類包括:


NSArray 唾糯、NSMutableArray

NSSet 柄驻、NSMutableSet

  • NSSet 對(duì)象所包含的“內(nèi)容”是無序的县习。而且在一個(gè) NSSet 對(duì)象中掘而,某個(gè)特定的對(duì)象只能出現(xiàn)一次(唯一性)迫悠。
  • NSSet 對(duì)象的最大用處是檢查某個(gè)對(duì)象是否存在鹏漆,NSSet 完成此類任務(wù)的速度比數(shù)組快得多。

NSSet 與 NSArray 的區(qū)別:

  • NSSet 和數(shù)組一樣创泄,是個(gè)數(shù)據(jù)容器艺玲。
  • 數(shù)組是有序的,NSSet是無序的鞠抑。
  • 數(shù)組可以容納重復(fù)對(duì)象饭聚,NSSet 不能。
  • 數(shù)組是有下標(biāo)的搁拙,NSSet 沒有下標(biāo)秒梳。

NSSet 的創(chuàng)建

// alloc 創(chuàng)建
NSSet *set1 = [[NSSet alloc] initWithObjects:@“張三”,@“李四”, nil];

// 類方法創(chuàng)建
NSSet *set2 = [NSSet setWithObjects:s@“張三”,@“李四”,nil];

其他集合常用創(chuàng)建方法

// 創(chuàng)建一個(gè)新的集合1箕速,集合2有兩個(gè)對(duì)象(a和b)
NSSet *set1 = [NSSet setWithObjects:@"a", nil];
NSSet *set2 = [set1 setByAddingObject:@"b"];
    
// 通過已有集合7和集合8酪碘,創(chuàng)建一個(gè)新的集合9
NSSet *set7 = [NSSet setWithObjects:@"a", nil];
NSSet *set8 = [NSSet setWithObjects:@"z", nil];
NSSet *set9 = [set7 setByAddingObjectsFromSet:set8];
    
// 通過已有的集合10和數(shù)組對(duì)象,創(chuàng)建一個(gè)新的集合11
NSArray *array = [NSArray arrayWithObjects:@"a", @"b", @"c", nil]; 
NSSet *set10 = [NSSet setWithObjects:@"z", nil];
NSSet *set11 = [set10 setByAddingObjectsFromArray:array]; 

NSSet 與 NSArray 相互轉(zhuǎn)換

// NSSet -> NSArray
NSArray *array = [set1 allObjects];

// NSArray --> NSSet
// 如果同一個(gè)對(duì)象在數(shù)組中出現(xiàn)多次盐茎,那么它只會(huì)添加一次到給定的集合兴垦。 每個(gè)對(duì)象在被添加到集合中時(shí)只會(huì)收到一次保留消息。
NSSet *set3 = [NSSet setWithArray:array];

返回集合元素的個(gè)數(shù)

NSUInteger count = [set1 count];

從容器中隨機(jī)取出一個(gè)元素

NSString *s = [set1 anyObject];

判斷對(duì)象是否在 NSSet 中已經(jīng)存在

- (BOOL)containsObject:(ObjectType)anObject;

示例:

BOOL isContain = [set1 containsObject:@"李四"]; 
  • NSSet 對(duì)象中的對(duì)象是無序的字柠,所以不能通過索引來訪問探越,只能向 NSSet 對(duì)象查詢某一個(gè)對(duì)象是否存在。
  • 當(dāng) NSSet 收到 - (BOOL)containsObject:(ObjectType)anObject; 消息時(shí)募谎,會(huì)在其包含的對(duì)象中查找和 anObject 相等的對(duì)象 (內(nèi)容相同扶关,地址可能不同,也就是說可能 【指針指向的內(nèi)容是相等的】,但是他們兩個(gè)【未必是同一塊地址】,返回 YES)。
  • 因此泵督,相同的變量(指針指向同一塊內(nèi)存地址)一定是相等的铜异,而相等的變量不一定是相同的哥倔。

NSMutableSet

NSMutableSet 是可變集合,它繼承自 NSSet揍庄。

常用方法

// 創(chuàng)建一個(gè)空的集合
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設(shè)置為集合3中的內(nèi)容
[set1 setSet:set3];
    
// 根據(jù)數(shù)組的內(nèi)容刪除集合中的對(duì)象
[set2 addObjectsFromArray:array];
[set2 removeObject:@"1"];
[set2 removeAllObjects];    

NSDictionary

  • 字典是由 鍵—值對(duì)組成的數(shù)據(jù)容器, 通過 key (鍵蚂子,通常是字符串)沃测,查找對(duì)應(yīng) value (值,可以是任意類型的對(duì)象)食茎。
  • 字典中的 鍵—值對(duì)是無序的蒂破。
  • 字典對(duì)象中的都是獨(dú)一無二的,如果想要在現(xiàn)存的鍵后再添加第二個(gè)對(duì)象别渔,第一個(gè)鍵—值對(duì)就會(huì)被替換掉附迷。
  • 字典中的key可以是任意類型,一般使用字符串作為一個(gè)元素的 key哎媚。
  • NSDictionary 是不可變字典喇伯。

字典的創(chuàng)建

NSArray *array1 = @[@"zhang3",@"zhangfei"];
NSArray *array2 = @[@"li4",@"liming"];
 
/*
 字典的結(jié)構(gòu)
 第一個(gè)元素:key:@"zhang"     value:array1
 第二個(gè)元素:key:@"li"        value:array2
 ...
 */

// 1.alloc方法創(chuàng)建
NSDictionary *dic1 = [[NSDictionary alloc] initWithObjectsAndKeys:
                      array1,@"zhang",
                      array2,@"li", nil];
                      
// xcode4.4以后對(duì)字典的創(chuàng)建和訪問,語法上做了優(yōu)化。
NSDictionary *dic11 = @{
                        @"zhang":array1,
                        @"li":array2
                       };
                       
// 2.類方法創(chuàng)建字典 
NSDictionary *dic2 = [NSDictionary dictionaryWithObjectsAndKeys: 
                                      array1,@"zhang",
                                      array2,@"li", nil];

返回字典元素個(gè)數(shù)

NSUInteger count = [dic1 count];

通過 key 獲取對(duì)應(yīng)的 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]; //通過下標(biāo)獲取對(duì)象key

  NSArray *names =[dic1 objectForKey:key]; //通過key獲取對(duì)應(yīng)的value
  NSLog(@"key=%@,value=%@",key,names);
}

// 2.快速遍歷
for (NSString *key in dic1) {
  NSArray *names = [dic1 objectForKey:key];
  NSLog(@"key=%@,value=%@",key,names);
}

刪除服務(wù)器返回的 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 是可變字典拨与,字典中的存儲(chǔ)是可以修改的稻据。NSMutableDictionary 繼承于 NSDictionary

創(chuàng)建可變字典

// 1.alloc 方法創(chuàng)建
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是重復(fù)的截珍,會(huì)將之前的value覆蓋掉
[mdic setObject:@"value" forKey:@"zhang"];
    
// 將另外一個(gè)字典所有的元素添加到mdic中
[mdic addEntriesFromDictionary:<#(nonnull NSDictionary *)#>];

刪除元素

// 1>根據(jù)Key刪除元素
[mdic removeObjectForKey:@"names"];
    
// 2>根據(jù)多個(gè)key刪除多個(gè)元素
[mdic removeObjectForKey:@[@"zhang",@"li"]];
    
// 3>刪除所有元素
[mdic removeAllObjects];

數(shù)組排序

第17章——NSMutableArray

過濾

  1. 匹配字符串:正則表達(dá)式
// 正則表達(dá)式:驗(yàn)證碼
- (BOOL) validateYzm:(NSString *)yzm {
    NSString *regex = @"^\\d{4}$";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];
    return [predicate evaluateWithObject:yzm];
}
  1. 過濾 collection
  • NSMutableArray 有一個(gè)名為 - filterUsingPredicate: 的方法攀甚,通過該方法可以很方便地剔除所有不能“滿足”傳入的 NSPredicate 對(duì)象的對(duì)象箩朴。
  • NSArray 有一個(gè)名為 filteredArrayUsingPredicate: 的方法岗喉,可以創(chuàng)建一個(gè)新的數(shù)組,包含所有能夠滿足傳入的 NSPredicate 對(duì)象的對(duì)象炸庞。
// 要收回?fù)碛形锲房們r(jià)值高于75美元的員工的物品
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"holder.valueOfAssets > 70"];

NSArray *toBeReclaimed = [allAssets filteredArrayUsingPredicate:predicate];

NSLog(@"toBeReclaimed:%@",toBeReclaimed);

NSSet 也有一個(gè)方法可以來做過濾钱床,代碼如下:

- (NSSet<ObjectType> *)filteredSetUsingPredicate:(NSPredicate *)predicate;

NSMutableSet 也有一個(gè)這樣的方法,如下:

- (void)filterUsingPredicate:(NSPredicate *)predicate;

NSNull

collection 對(duì)象不能保存 nil埠居。如果要將“空洞”加入集合對(duì)象中查牌,可以使用 NSNull 類。NSNull 類只有一個(gè)實(shí)例滥壕,代表“空”纸颜。

示例代碼如下:

NSMutableArray *hotel = [[NSMutableArray alloc] init];

// 底樓大廳
[hotel addObject:@"lobby"];

// 二樓泳池
[hotel addObject:@"pool"];

// 三樓未建,為空R镩佟P菜铩唠倦!
[hotel addObject:[NSNull null]];

// 四樓臥室
[hotel addObject:@"bedrooms"];

NSIndexSet

這個(gè)類用于存儲(chǔ)有序的索引到某種數(shù)據(jù)結(jié)構(gòu),比如數(shù)組涮较。例如稠鼻,使用這個(gè)類可以生成一份數(shù)組對(duì)象的索引號(hào)清單,這些對(duì)象滿足指定的查詢條件狂票。

- (NSUInteger)indexOfObjectPassingTest:

示例代碼:

NSArray *array = @[@1, @2, @3, @4, @5];

// 遍歷數(shù)組候齿,取出滿足條件的數(shù)組索引
NSUInteger result = [array indexOfObjectPassingTest:^BOOL(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    if ([(NSNumber *)obj intValue] % 2 == 0) {
        return YES;
    }else {
        return NO;
    }
}];

// 如果找到一個(gè)匹配,則查看并打印此項(xiàng)
if (result != NSNotFound) {
    NSLog(@"%@",array[result]); 
}

// >輸出:2

結(jié)論:只可以返回一個(gè)索引闺属。

- (NSIndexSet *)indexesOfObjectsPassingTest:

示例代碼:

NSArray *array = @[@1, @2, @3, @4, @5];

// 遍歷數(shù)組慌盯,取出滿足條件數(shù)組的所有索引
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 常用方法

// 創(chuàng)建一個(gè)空的索引集合
+ (instancetype)indexSet;
// 給定索引創(chuàng)建索引集合
+ (instancetype)indexSetWithIndex:(NSUInteger)value;
// 給定索引范圍創(chuàng)建索引集合
+ (instancetype)indexSetWithIndexesInRange:(NSRange)range;

- (instancetype)initWithIndexesInRange:(NSRange)range NS_DESIGNATED_INITIALIZER;
// 根據(jù)另一個(gè)索引集合創(chuàng)建索引集合
- (instancetype)initWithIndexSet:(NSIndexSet *)indexSet NS_DESIGNATED_INITIALIZER;

// 給定索引值初始化索引集合
- (instancetype)initWithIndex:(NSUInteger)value;

// 判斷兩個(gè)索引集合是否相等
- (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));

// ...
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市掂器,隨后出現(xiàn)的幾起案子润匙,更是在濱河造成了極大的恐慌,老刑警劉巖唉匾,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件孕讳,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡巍膘,警方通過查閱死者的電腦和手機(jī)厂财,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來峡懈,“玉大人璃饱,你說我怎么就攤上這事》究担” “怎么了荚恶?”我有些...
    開封第一講書人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長磷支。 經(jīng)常有香客問我谒撼,道長,這世上最難降的妖魔是什么雾狈? 我笑而不...
    開封第一講書人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任廓潜,我火速辦了婚禮,結(jié)果婚禮上善榛,老公的妹妹穿的比我還像新娘辩蛋。我一直安慰自己,他們只是感情好移盆,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開白布悼院。 她就那樣靜靜地躺著,像睡著了一般咒循。 火紅的嫁衣襯著肌膚如雪据途。 梳的紋絲不亂的頭發(fā)上钮呀,一...
    開封第一講書人閱讀 52,475評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音昨凡,去河邊找鬼爽醋。 笑死,一個(gè)胖子當(dāng)著我的面吹牛便脊,可吹牛的內(nèi)容都是我干的蚂四。 我是一名探鬼主播,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼哪痰,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼遂赠!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起晌杰,我...
    開封第一講書人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤跷睦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后肋演,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抑诸,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年爹殊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蜕乡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡梗夸,死狀恐怖层玲,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情反症,我是刑警寧澤辛块,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站铅碍,受9級(jí)特大地震影響润绵,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜该酗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一授药、第九天 我趴在偏房一處隱蔽的房頂上張望士嚎。 院中可真熱鬧呜魄,春花似錦、人聲如沸莱衩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽笨蚁。三九已至睹晒,卻和暖如春趟庄,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背伪很。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來泰國打工戚啥, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人锉试。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓猫十,卻偏偏與公主長得像,于是被迫代替她去往敵國和親呆盖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拖云,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容