OC foudation框架(下)的學習

OCfoudation框架(下)

前面學習了有關OCfoudation框架的部分內容,我們現在對于后面的內容繼續學習。


文章目錄

  • OCfoudation框架(下)
    • 數組(NSArray和NSMutableArray)
      • 對集合元素整體調用方法
      • 排序
      • 使用枚舉器遍歷元素
      • 快速枚舉(for in)
      • 可變數組
    • 集合(NSSet 與 NSMutableSet)
      • 功能與用法
      • 判斷元素重復的標準
      • NSMutableSet的功能和用法
      • NSCountedSet的用法
      • 有序集合
    • 字典
      • 功能和用法
      • 對key排序
      • 對key進行過濾
      • 用自定義類作為key
      • NSmutableDictionary

數組(NSArray和NSMutableArray)

創建數組的常見方法介紹:

  • arrary:創建一個不包含任何元素的空NSArray
  • arrayWithContentsOfFile:/initWithContentsOfFile:讀取文件內容來創建
  • arrayWithObject:創建僅包含指定元素的NSArray
  • arrayWithObjects:創建包含指定的N個元素的NSArray;

下面我們通過一段代碼來運用這個數組的一些方法。

int main(int argc, const char * argv[]) {@autoreleasepool {NSArray* array = [NSArray arrayWithObjects:@"iOS", @"Android", @"Java講義", @"Html", @"structs", @"nanxun", nil];NSLog(@"first: %@",[array objectAtIndex:0]);NSLog(@"last:%@", [array lastObject]);NSArray* arr1 = [array objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(2, 3)]];NSLog(@"%@",arr1);NSLog(@"Android:%ld", [array indexOfObject:@"Android"]);NSLog(@"Android in (2,5): %ld", [array indexOfObject:@"Android" inRange:NSMakeRange(2, 3)]);array = [array arrayByAddingObject:@"nannan"];array = [array arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:@"krystal", @"zitai", nil]];for (int i = 0; i < array.count; i++) {NSLog(@"%@", [array objectAtIndex:i]);}NSArray* arr2 = [array subarrayWithRange:NSMakeRange(5, 3)];[arr2 writeToFile:@"/Users/nanxun/Documents/testoc/foudation study/foudation study/myFile.txt" atomically:YES];}return 0;
}

打印結果如下:

在這里插入圖片描述

接下來分析一下相關內容,先看我們在(2, 5)位置尋找Android的結果,發現他是一個數字9223372036854775807,這個數值實際上是NSNotFound這個常量的值,就下來我們通過兩種方式在后面添加元素,arrayByAddingObject添加單個元素,arrayWithObjects方法是將一個數組中的元素全部追加到原數組后面。

同時可以看到,我門用程序直接輸出數組的話,可知道中文無法正常輸出,這個會轉化成/U75af格式輸出。

我們下面分析在NSArray中能否判斷指定元素位于NSArray集合中的索引,我們的標準是什么?這個標準就是我們的isEqual: 方法,比較是否相同,為了理解這個部分的內容,我們建立一個FKUser來幫助自己理解相關內容。

接口部分

@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

實現部分

@implementation FKUser
- (id) initWithName:(NSString *)aName pass:(NSString *)aPass {if (self = [super init]) {self.name = aName;self.pass = aPass;}return self;
}
- (void) say:(NSString *)content {NSLog(@"%@說:%@", self.name, content);
}
- (BOOL) isEqual:(id)object {if (self == object) {return YES;}if ([object class] == [FKUser class]) {FKUser* target = (FKUser*) object;return [self.name isEqualToString:target.name] && [self.pass isEqualToString: target.pass];}return NO;
}
- (NSString*) description {return [NSString stringWithFormat:@"FKUser[_name = %@, _pass = %@]", self.name, self.pass];
}
@end

主函數部分

int main(int argc, const char * argv[]) {@autoreleasepool {NSArray* array = [NSArray arrayWithObjects:[[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"], nil];FKUser* newUser = [[FKUser alloc] initWithName:@"zhu" pass:@"654"];NSUInteger pos = [array indexOfObject:newUser];NSLog(@"newUser的位置為%ld", pos);}return 0;
}

輸出結果為下:在這里插入圖片描述

這里我們發現了一個事情就是我們重新創建了一個對象,雖然該對象與集合中的任何對象都不相同,但是我們的程序還是可以返回該FKUser對象在該集合中的索引,這是因為他調用的是我們的isEqual方法

對集合元素整體調用方法

如果只是簡單的調用集合元素的方法,主要有兩種方法:

  • makeObjectPerformSelector:依次調用NSArray集合中每個元素的指定方法需要傳入一個SEL參數
  • makeObjectsPerformSelcetor:withObject:一次調用集合中每個元素的指定方法,該方法第一個參數SEL用于指定調用那個方法,第二個參數用于調用集合元素方法時候傳入參數;第三參數用來控制是否終止迭代,如果在處理某個元素后,將第三個元素復制為YES,該方法就終止迭代調用。

如果希望對集合中所有元素進行隱式遍歷,并使用集合元素來執行某一段代碼,可以使用以下三種方式

  • enumerateObjectUsingBlock: 遍歷集合中的所有元素,并依次使用元素來執行指定的代碼塊
  • enumerateObjectsWithOptions:usingBolck: 和上面的差別就是可以傳入一個號控制遍歷的選項。
  • enumerateObjectAtIndexes:options:usingBlock: 這個它增加了一個遍歷指定范圍內的元素,并一次使用元素來執行指定的代碼塊。
int main(int argc, const char * argv[]) {@autoreleasepool {NSArray* array = [NSArray arrayWithObjects:[[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"], nil];[array makeObjectsPerformSelector:@selector(say:) withObject:@"下午好,NSArray真強大"];NSString* content = @"瘋狂iOS講義";[array enumerateObjectsAtIndexes: [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(2, 2)]options:NSEnumerationReverse usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {NSLog(@"正在處理第%ld個元素,%@",idx, obj);[obj say:content];}];}return 0;
}

打印結果如下:

在這里插入圖片描述

這兩段代碼,主要調用了兩個函數,一個是調用了**makeObjectsPerformSelector:**方法通過withObjects為say方法傳入參數.

第二個則是應用了enumerateObjectsAtIndexes:options:usingBlock:方法并用這些元素來這些指定的代碼塊,傳入的代碼塊參數就代表程序對每個集合元素迭代執行的代碼體。(筆者這里對與Block不了解,還需要后續學習進行補充)。

排序

對數組的排序函數主要有三種:

  • sortedArrayUsingFunction:contes:該方法使用排序函數對集合元素進行一個排序,該排序函數必須返回NSOrderedDesceding,NSOrderedAscending,NSOrderedSame三個枚舉常量。
  • sortedArrayUsingSelector:該方法使用集合元素自身的方法對集合元素進行排序,它的排序函數同樣會返回上面給出的三個枚舉值。
  • sortedArrayUsingComparator:該方法使用代碼塊對與集合元素進行排序

三種方法的返回值都是一個排好序的NSArray對象。

下面演示一下我們對于NSArray集合元素進行一個排序。

NSInteger inSort (id num1, id num2, void* context) {int v1 = [num1 intValue];int v2 = [num2 intValue];if (v1 < v2) {return NSOrderedAscending;} else if (v1 == v2) {return NSOrderedSame;} else {return NSOrderedDescending;}
}
int main(int argc, const char * argv[]) {@autoreleasepool {NSArray* array1 = [NSArray arrayWithObjects:@"C++",@"Python",@"Perl",@"C",@"Objective-C",@"Ruby", nil];array1 = [array1 sortedArrayUsingSelector:@selector(compare:)];NSLog(@"%@", array1);NSArray* array2 = [NSArray arrayWithObjects:[NSNumber numberWithInt:20], [NSNumber numberWithInt:12], [NSNumber numberWithInt:-8],[NSNumber numberWithInt:50], [NSNumber numberWithInt:19],nil];array2 = [array2 sortedArrayUsingFunction:inSort context:nil];NSLog(@"%@", array2);NSArray* array3 = [array2 sortedArrayUsingComparator:^(id obj1, id obj2) {if ([obj1 intValue] > [obj2 intValue]) {return NSOrderedDescending;} else if ([obj1 intValue] < [obj2 intValue]) {return NSOrderedAscending;} else {return NSOrderedSame;}}];NSLog(@"%@", array3);}return 0;
}

打印結果如下:

在這里插入圖片描述

在上述代碼中間我們示范了三種對于NSArrary進行排序的三種方法,第一種是調用NSString自身的compaer:方法進行排序(compare的比較和成語言中的strcmp()函數相似)。

后面是兩種不同的方法,一個是調用代碼塊,一個是調用函數的方法。

使用枚舉器遍歷元素

我們有兩個方法獲得枚舉器

  • objectEnumerator:正序遍歷
  • reverseObjectEnumerator:逆序遍歷

枚舉器的方法有以下兩個

  • allObjects:獲取枚舉集合中所有的元素
  • reverseObjectEnumerator:獲取被枚舉集合中的下一個元素。
int main(int argc, const char * argv[]) {@autoreleasepool {NSArray* array1 = [NSArray arrayWithObjects:@"C++",@"Python",@"Perl",@"C",@"Objective-C",@"Ruby", nil];NSEnumerator* en = [array1 objectEnumerator];id object;while (object = [en nextObject]) {NSLog(@"%@", object);}NSLog(@"");NSEnumerator* an = [array1 reverseObjectEnumerator];while (object = [an nextObject]) {NSLog(@"%@", object);}}return 0;
}

打印結果為:

在這里插入圖片描述

一種是升序,另一種是降序。

快速枚舉(for in)

快速枚舉的語法格式如下:

for(type variableName in collection) {//variableName自動迭代訪問每一個元素
}

tips:這里面如果用快速枚舉來遍歷NSDictionary對象的時候,它代表的是key值

下面給出一個示范

int main(int argc, const char * argv[]) {@autoreleasepool {NSArray* array1 = [NSArray arrayWithObjects:@"C++",@"Python",@"Perl",@"C",@"Objective-C",@"Ruby", nil];for (id object in array1) {NSLog(@"%@", object);}}return 0;
}

打印結果如下

在這里插入圖片描述

可變數組

NSArray代表元素不可變的集合,一旦創建成功,程序不能向集合調價新的元素,這時候我們就要運用到我們的NSMutableArray.

它給出了增加(add),刪除(remove),替換(replace)元素的方法。

NSMutableArray還提供了sortUsingSelector:、sortUsingComparator:、sortUsingFunction: context:方法,它們與前面介紹的NSArray的排序的方法類似,區別是NSArray的排序的方法返回的是一個新的NSArray對象,而NSMutableArray返回的是排序后的原來的對象。

下面給出代碼示范

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 - 1, 1)];//去掉最后一個字符[result appendString:@"]"];return result;
}
int main(int argc, const char * argv[]) {@autoreleasepool {NSMutableArray* array1 = [NSMutableArray arrayWithObjects:@"C++",@"Python",@"Perl",@"C",@"Objective-C",@"Ruby", nil];[array1 addObject:@"Java"];NSLog(@"%@", NSCollectionToString(array1));[array1 addObjectsFromArray:[NSArray arrayWithObjects:@"Js", @"Ts", nil]];NSLog(@"%@", NSCollectionToString(array1));[array1 insertObject:@"Android" atIndex:2];NSLog(@"%@", NSCollectionToString(array1));[array1 insertObjects:[NSArray arrayWithObjects:@"web",@"server", nil] atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(3, 2)]];NSLog(@"%@", NSCollectionToString(array1));[array1 removeLastObject];NSLog(@"%@", NSCollectionToString(array1));[array1 removeObjectAtIndex:5];NSLog(@"%@", NSCollectionToString(array1));[array1 replaceObjectAtIndex:2 withObject:@"瘋狂iOS"];NSLog(@"%@", NSCollectionToString(array1));}return 0;
}

打印結果如下:

在這里插入圖片描述

集合(NSSet 與 NSMutableSet)

NSSet集合不允許包含相同的元素(它沒有明顯的順序),如果試圖將兩個相同的元素放在同一個NSSet集合中,則只會保留一個元素

功能與用法

實際上,NSArray與NSSet依然有大量的相似之處。

  • 都可以通過count方法獲取集合元素數量
  • 可以用快速枚舉遍歷集合元素
  • 可以通過objectEnumerator方法獲取NSEnumerator枚舉器對集合元素遍歷。
  • 提供了makeObjectsPerformSelector:方法對集合元素真題調用某個方法

接下來我們介紹一下NSSet的常用方法

  • setByAddingObject:向集合中添加一個新元素,返回添加元素后的新集合
  • setByAddingObjectsFromSet:使用NSSet集合向集合中添加多個新元素,返回新集合
  • setByAddingObjectsFromArray:使用NSArray集合向集合中添加多個新元素,返回新集合
  • allObjects:返回集合中所有元素組成的NSArray
  • anyObject:返回集合中的某個元素。(但是并不保證隨機返回集合元素)。
  • containsObject:判斷集合是否包含指定元素
  • Member:判斷該集合是否包括與該參數相等的元素,如果包含就返回相等的元素,反之則返回nil。
  • objectsPassingTest:需要傳入一個代碼塊對集合元素進行一個過濾,滿足該代碼塊的集合元素會被保留下來并組成一個新的NSSet集合作為返回值
  • objectsWithOptions:passingTest:和前一個方法的功能基本相似,只是可以額外地傳入一個NSEnumerationOptions作為迭代參數
  • isSubsetOfSet:判斷是否為一個子集
  • intersectsSet:判斷是否有交集
  • isEqualToset:判斷集合是否相同

下面給出一段代碼來理解相關內容

NSString *NSCollectionToString(id array) {NSMutableString *result = [NSMutableString stringWithString:@"["];for (id obj in array) {[result appendString: [obj description]];[result appendString:@","];}NSUInteger len = [result length];[result deleteCharactersInRange:NSMakeRange(len - 1, 1)];//去掉最后一個字符[result appendString:@"]"];return result;
}
int main(int argc, const char * argv[]) {@autoreleasepool {NSSet* set1 = [NSSet setWithObjects:@"iOS", @"Andirod",@"web",@"server", nil];NSLog(@"set個數為%ld", [set1 count]);NSLog(@"%@", NSCollectionToString(set1));NSSet* set2 = [NSSet setWithObjects:@"krystal",@"xiyang",@"fenfneko",@"web", nil];NSLog(@"%@", NSCollectionToString(set2));set1 = [set1 setByAddingObject:@"shenyi"];NSSet* s1 = [set1 setByAddingObjectsFromSet:set2];NSLog(@"并集合%@", NSCollectionToString(s1));BOOL bo = [set2 isSubsetOfSet: set1];NSLog(@"set2是否是set1子集集%ld",bo);BOOL bb = [set1 containsObject:@"Andirod"];NSLog(@"是否包含Andirod:%ld", bb);NSLog(@"從set1中取出一個%@",[set1 anyObject]);NSSet* fileteredSet = [set1 objectsPassingTest:^(id obj, BOOL *stop) {return (BOOL)([obj length] > 3);}];NSLog(@"set1中元素長度大于8的集合元素有%@",NSCollectionToString(fileteredSet));}return 0;
}

下面是代碼的結果:

在這里插入圖片描述

這部分內容主要是一個演示相關代碼的一個作用。

判斷元素重復的標準

這里涉及到了一個Hash表的內容,我們每存入一個元素那么我們的NSSet會帶調用該對象的一個Hash方法來計算一個Hash值,然后根據HashCode計算出元素在底層Hash表中的存儲位置。如果出現了兩個元素通過了isEqual方法但是它倆的值相同,那么我們這里的方式是通過鏈表將這兩個元素連接起來。

這里我們就可以知道NSSet中判斷兩個元素是否相等的標準如下:

  • 兩個對象通過isEqual的方法返回YES
  • 兩個對象的hash方法的返回值也相等
int main(int argc, const char * argv[]) {@autoreleasepool {NSSet* array = [NSSet setWithObjects:[[FKUser alloc] initWithName:@"sun" pass:@"123"],[[FKUser alloc] initWithName:@"bai" pass:@"345"],[[FKUser alloc] initWithName:@"zhu" pass:@"123"],[[FKUser alloc] initWithName:@"tang" pass:@"178"],[[FKUser alloc] initWithName:@"niu" pass:@"155"], nil];NSLog(@"元素個數為%ld", [array count]);NSLog(@"%@", NSCollectionToString(array));}return 0;
}

這是我們之前用過的FKUser類別,我們在這個類別中間定義了我們的isEqual:方法它只要name和oass相同就說明了我們的兩個對象是相同的。但是打印結果卻不符合我們的一個預期

在這里插入圖片描述

發現出現了兩個相同的元素,因此我們要重寫一下Hash方法。

- (NSUInteger) hash {NSLog(@"===hash===");NSUInteger nameHash = _name == nil ? 0 : [_name hash];NSUInteger passHash = _pass == nil ? 0 : [_pass hash];return nameHash * 31 + passHash;
}

修改之后發現結果就恢復正常了。

在這里插入圖片描述

這里我們發現了我們執行了5次Hash方法,這一步說明我們每次添加一個集合與安素,總是會先調用該元素的Hash方法,在重寫這兩種方法的時候,我們的目的主要是為了滿足NSSet的性質,為了保證哦我們的NSSet保持一個較高的性能。

tips:Hash方法對于NSSet是非常重要的,下面給出重寫Hash方法的基本原則。

  • 同一對象返回的Hash值應該是相同的
  • isEqual:方法比較返回YES的時候,這兩個對象的Hash應返回相等的值·
  • 對象中所有被isEqual比較標準的實例變量都應該用來就算hashCode值。

一般情況我們的返回值都寫成[f1 hash] * (質數) + [f2 hash]

NSMutableSet的功能和用法

和array相似,add(增加),remove(刪除)。

主要要記住交,并,交,差集的函數

  • unionSet:計算并集
  • minusSet:計算差集
  • intersectSet:計算交集
  • setSet:用后一個元素替換已有集合中的所有元素
int main(int argc, const char * argv[]) {@autoreleasepool {NSMutableSet* set1 = [NSMutableSet setWithCapacity:10];[set1 addObject:@"Java"];NSLog(@"add a one %@",NSCollectionToString(set1));[set1 addObjectsFromArray:[NSArray arrayWithObjects:@"krystal",@"xiyang",@"zzr", nil]];NSLog(@"add many %@", NSCollectionToString(set1));[set1 removeObject:@"xiyang"];NSLog(@"remove one %@",NSCollectionToString(set1));NSMutableSet* set2 = [NSSet setWithObjects:@"fenfenko",@"shenyi", nil];//[set1 unionSet: set2];//[set1 minusSet: set2];//[set1 intersectSet:set2];[set1 setSet:set2];NSLog(@"%@", NSCollectionToString(set1));}return 0;
}

打印結果如下:

在這里插入圖片描述

NSCountedSet的用法

NSCountedSet主要是有一個特色就是它會為每一個元素增加一個該元素出現的個數,我們可以不可以添加元素,但是如果我們添加的元素重復了,但是會將該元素的添加次數加1.刪除元素的時候也是將這個元素添加次數減1,知道它為0的時候,這個元素才會真正的從NSCountedSet中刪除。

int main(int argc, const char * argv[]) {@autoreleasepool {NSCountedSet* set1 = [NSCountedSet setWithObjects:@"iOS講義",@"Android",@"Java", nil];[set1 addObject:@"Java"];[set1 addObject:@"Java"];NSLog(@"%@", NSCollectionToString(set1));NSLog(@"Java的添加次數為%ld", [set1 countForObject:@"Java"]);[set1 removeObject:@"Java"];NSLog(@"%@", NSCollectionToString(set1));NSLog(@"Java的添加次數為%ld", [set1 countForObject:@"Java"]);[set1 removeObject:@"Java"];[set1 removeObject:@"Java"];NSLog(@"%@", NSCollectionToString(set1));NSLog(@"Java的添加次數為%ld", [set1 countForObject:@"Java"]);}return 0;
}

打印結果為:

在這里插入圖片描述

這里就很好的體現了我們的NSCountedSet的特色。

有序集合

NSOrderedSet最主要的點在于可以保持與安素的添加順序,而且每一個元素都有縮影,可以根據縮影來操作元素。

int main(int argc, const char * argv[]) {@autoreleasepool {NSOrderedSet* set = [NSOrderedSet orderedSetWithObjects:[NSNumber numberWithInt:40],[NSNumber numberWithInt:12],[NSNumber numberWithInt:-9],[NSNumber numberWithInt:20], nil];NSLog(@"first :%@", [set firstObject]);NSLog(@"last:%@", [set lastObject]);NSLog(@"索引為2的元素:%@", [set objectAtIndex:2]);NSIndexSet* indexSet = [set indexesOfObjectsPassingTest:^(id obj, NSUInteger idx, BOOL* stop) {return (BOOL)([obj intValue] > 10); // 返回大于10的值}];NSLog(@"%@", indexSet);}return 0;
}

請添加圖片描述

字典

這里的字典和C++中的map大致相同,它擁有一個鍵值對,所有key放在一個Set集合中,但是如果我們采用一個allKeys方法來返回卻是一個NSArray。

功能和用法

初始化方法:一般以dictionary開頭

在這里插入圖片描述

訪問方式:

請添加圖片描述

@implementation NSDictionary (print)
- (void)print {NSMutableString* result = [NSMutableString stringWithString:@"["];for (id key in self) {[result appendString:[key description]];[result appendString:@"="];[result appendString:[self[key] description]];[result appendString:@", "];}NSUInteger len = [result length];[result deleteCharactersInRange:NSMakeRange(len - 1, 1)];[result appendString:@"]"];NSLog(@"%@", result);
}

這段代碼演示了兩種經典的語法,通過key獲取value值 self[key]

下面給出一段代碼來演示相關內容。

int main(int argc, const char * argv[]) {@autoreleasepool {NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:[[FKUser alloc] initWithName:@"krystal" pass:@"24"], @"one", [[FKUser alloc] initWithName:@"xiyang" pass:@"33"], @"two",[[FKUser alloc] initWithName:@"flandre" pass:@"111"], @"three", [[FKUser alloc] initWithName:@"fenfenko" pass:@"2222"], @"four",[[FKUser alloc] initWithName:@"krystal" pass:@"24"], @"five", nil];[dict print];NSLog(@"有多少個key-value對:%ld", [dict count]);NSLog(@"dict的所有key為%@", [dict allKeys]);NSLog(@"krystal對應的所有key為%@", [dict allKeysForObject:[[FKUser alloc] initWithName:@"krystal" pass:@"24"]]);NSEnumerator* en = [dict objectEnumerator];NSObject* value;while (value = [en nextObject]) {NSLog(@"%@", value);}[dict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL* stop) {NSLog(@"key的值為:%@",key);[value say:@"101牛逼"];}];}return 0;
}

請添加圖片描述

請添加圖片描述

這里就演示了我們的dictionary的相關的代碼演示。

對key排序

他和對于數組的排序一樣,都是類似的,它的返回值同樣是那三個關鍵字:NSOrderedAscendingNSOrderedDescendingNSOrderedSame

接下來示范一下排序。

NSString *NSCollectionToString(id array) {NSMutableString *result = [NSMutableString stringWithString:@"["];for (id obj in array) {[result appendString: [obj description]];[result appendString:@","];}NSUInteger len = [result length];[result deleteCharactersInRange:NSMakeRange(len - 1, 1)];//去掉最后一個字符[result appendString:@"]"];return result;
}
int main(int argc, const char * argv[]) {@autoreleasepool {NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:@"iOS",@"one",@"Android",@"two",@"Java",@"three",@"Objective-c",@"four", nil];[dict print];NSArray* keyArr1 = [dict keysSortedByValueUsingSelector:@selector(compare:)];NSLog(@"%@", keyArr1);NSArray* keyArr2 = [dict keysSortedByValueUsingComparator:^(id value1, id value2) {if ([value1 length] > [value2 length]) {return NSOrderedDescending;} else if ([value1 length] == [value2 length]) {return NSOrderedSame;} else {return NSOrderedAscending;}}];NSLog(@"%@", keyArr2);}return 0;
}

打印結果如下

請添加圖片描述

對key進行過濾

  • keysOfEntriesPassingTest:使用代碼塊迭代處理key-value對,只有符合代碼塊條件的會留下來。一共接收三個參數,第一個是正在迭代處理的key,第二個參數代表正在迭代處理的value,第三個參數代表是是否需要繼續迭代,如果第三個參數設置成NO,這個方法就會立即停止迭代。
  • keysOfEntriesWithOptions:passingTest:該方法的功能和前一個方法的功能基本相同,可以額外傳入一個附加的NSEnumerationOptions的選項參數。
int main(int argc, const char * argv[]) {@autoreleasepool {NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:89], @"Objective-C",[NSNumber numberWithInt:69], @"Ruby",[NSNumber numberWithInt:75], @"Python",[NSNumber numberWithInt:109], @"Prel", nil];[dict print];NSSet* keySet = [dict keysOfEntriesPassingTest:^(id key, id value, BOOL* stop) {return (BOOL)([value intValue] > 80);}];NSLog(@"%@", keySet);}return 0;
}

打印結果如下:

請添加圖片描述

用自定義類作為key

我們可以用自己定義的類來作為key,但是要滿足兩個要求:

  • 正確重寫isEqual:方法和hash方法
  • 自定義類實現了copyWithZone:方法,最好可以返回對象的不可變副
int main(int argc, const char * argv[]) {@autoreleasepool {FKUser* u1 = [[FKUser alloc] initWithName:@"krystal" pass:@"24"];NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:@"one", [[FKUser alloc] initWithName:@"xiyang" pass:@"23"],@"two", [[FKUser alloc] initWithName:@"flandre" pass:@"22"],@"three", [[FKUser alloc] initWithName:@"xiyang" pass:@"23"],@"four", [[FKUser alloc] initWithName:@"fenfenko" pass:@"19"],@"five", [[FKUser alloc] initWithName:@"niu" pass:@"155"],@"six", u1, nil];u1.pass = nil;[dict print];}return 0;
}

打印結果如下:

請添加圖片描述

這里我們可以看到它會讓重復的key出現一次。

NSmutableDictionary

它其實也主要是提供了可以增加key-value對,和刪除key-value對的一系列方法

請添加圖片描述

代碼演示

int main(int argc, const char * argv[]) {@autoreleasepool {NSMutableDictionary* dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"iOS", @"99", nil];dict[@"99"] = @"iOSS";[dict print];dict[@"Android"] = @"ddd";[dict print];NSDictionary* dict2 = [NSDictionary dictionaryWithObjectsAndKeys:@"Java", @"sss", @"python", @"struct", nil];[dict addEntriesFromDictionary:dict2];[dict print];[dict removeObjectForKey:@"sss"];[dict print];}return 0;
}

打印結果如下:

請添加圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/9851.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/9851.shtml
英文地址,請注明出處:http://en.pswp.cn/web/9851.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

會賺錢的人都在做這件事:你了解嗎?

在我們日常生活的點滴中&#xff0c;以及在各種場合的交互中&#xff0c;利他思維始終扮演著不可或缺的角色。當我們追求合作與共贏時&#xff0c;單方面的自我立場顯然是不夠的&#xff0c;真正的關鍵在于換位思考&#xff0c;尋找并滿足對方的需求。 互利互贏的核心理念正是利…

設置docker容器時區

設置docker容器時區 查看當前系統時間 1.1 查看當前系統版本 cat /etc/issue1.2 查看當前系統時間 date查看鏡像默認時間 2.1 alpine鏡像 sudo docker run -it --rm alpine date2.2 ubuntu鏡像 sudo docker run -it --rm ubuntu date2.3 centos鏡像 sudo docker run -it --rm …

虛擬知識付費系統源碼推薦,在線教育雙十一怎么做活動?

又是一年光棍節&#xff0c;啊不是&#xff0c;剁手節。小伙伴們早就摩拳擦掌準備剁手了&#xff0c;這個時候&#xff0c;幾乎所有線上平臺都行動起來了&#xff0c;而在線教育行業也沒有閑著。如今&#xff0c;雙十一已經成為了各大在線教育公司用來變現的一個大殺器&#xf…

ruoyi-vue-pro 使用記錄(4)

ruoyi-vue-pro 使用記錄&#xff08;4&#xff09; CRM數據庫線索客戶商機合同回款產品其他 CRM 文檔 主要分為 6 個核心模塊&#xff1a;線索、客戶、商機、合同、回款、產品。 線索管理以 crm_clue 作為核心表客戶管理以 crm_customer 作為核心表商機管理以 crm_business 作…

JavaScript數組(Array)方法 - toReversed、toSorted、toSpliced

最近發現幾個數組方法&#xff0c;是一些常規方法的升級版&#xff0c;比較有意思&#xff0c;分享給大家 文章目錄 一、溫故二、知新toReversedtoSortedtoSpliced 一、溫故 我們先來回顧幾個比較常用的方法&#xff1a;reverse&#xff0c;sort&#xff0c;splice眾所周知&a…

luceda ipkiss教程 69:導出器件或者線路的三維模型

ipkiss 3.12版加入write_obj函數&#xff0c;可以直接輸出器件的三維模型。 如&#xff0c;輸出自定義的mmi的三維模型&#xff1a; 代碼如下&#xff1a; from si_fab import all as pdk from ipkiss3 import all as i3class MMI1x2(i3.PCell):"""MMI with …

kaldi學習參考

HMM模型 https://www.cnblogs.com/baixf-xyz/p/16777438.htmlhttps://www.cnblogs.com/baixf-xyz/p/16777438.htmlGMM-HMM 基于GMM-HMM的語音識別系統https://www.cnblogs.com/baixf-xyz/p/16777439.html https://www.cnblogs.com/baixf-xyz/p/16777426.htmlhttps://www.cnbl…

全棧開發之路——前端篇(6)生命周期和自定義hooks

全棧開發一條龍——前端篇 第一篇&#xff1a;框架確定、ide設置與項目創建 第二篇&#xff1a;介紹項目文件意義、組件結構與導入以及setup的引入。 第三篇&#xff1a;setup語法&#xff0c;設置響應式數據。 第四篇&#xff1a;數據綁定、計算屬性和watch監視 第五篇 : 組件…

碼一點網站

Linux命令查詢網站 https://www.lzltool.com/LinuxCommand/Index 小林 x 圖解計算機基礎 https://xiaolincoding.com/ 代碼隨想錄 https://programmercarl.com/ 可用于爬蟲 https://books.toscrape.com/ 數據結構可視化 https://www.cs.usfca.edu/~galles/visualization/ …

fastText-文本分類

fastText介紹 fastText是一個快速文本分類算法,與基于神經網絡的分類算法相比有兩大優點: 1、fastText在保持高精度的情況下加快了訓練速度和測試速度 2、fastText不需要預訓練好的詞向量,fastText會自己訓練詞向量 3、fastText兩個重要的優化:Hierarchical Softmax、N-gr…

387.字符串中的第一個唯一字符

刷算法題&#xff1a; 第一遍&#xff1a;1.看5分鐘&#xff0c;沒思路看題解 2.通過題解改進自己的解法&#xff0c;并且要寫每行的注釋以及自己的思路。 3.思考自己做到了題解的哪一步&#xff0c;下次怎么才能做對(總結方法) 4.整理到自己的自媒體平臺。 5.再刷重復的類…

YUV中Y顏色模型的采樣

YUV的特點 相對于表示顏色的GUI&#xff0c; YUI將亮度&#xff08;用Y表示&#xff09;與色調&#xff08;用U和V表示&#xff09;分開來表示。又因為人類視網膜上的視網膜桿細胞要多于視網膜錐細 胞&#xff0c;說得通俗一些&#xff0c;視網膜桿細胞的作用就是識別亮度&…

LabVIEW MEMS電容式壓力傳感器測試系統

LabVIEW MEMS電容式壓力傳感器測試系統 隨著微電子技術的發展&#xff0c;MEMS&#xff08;微電機系統&#xff09;技術在各個領域得到了廣泛應用。MEMS電容式壓力傳感器以其高靈敏度、小尺寸、低功耗等優點&#xff0c;在微傳感器領域占據了重要的地位。然而&#xff0c;這些…

Smma-net:一種基于音頻線索的目標說話人提取網絡,具有譜圖匹配和相互關注功能

SMMA-NET: AN AUDIO CLUE-BASED TARGET SPEAKER EXTRACTION NETWORK WITH SPECTROGRAM MATCHING AND MUTUAL ATTENTION 第二章 目標說話人提取之《Smma-net:一種基于音頻線索的目標說話人提取網絡&#xff0c;具有譜圖匹配和相互關注功能》 文章目錄 SMMA-NET: AN AUDIO CLUE-…

程序員的多維智慧:技術修煉、人際交往與投資哲學

程序員不應該只會埋頭敲代碼&#xff0c;要多看看書&#xff0c;多學習... 1.程序員技術 保持嚴謹的作風&#xff0c;實事求是&#xff0c;記錄現象&#xff0c;找準依據&#xff0c;可以做出假設&#xff0c;問題的解釋和結論必須能完整、全面符合現象和各種認知邏輯。 絕不…

【算法入門賽】B. 自助店評分(C++、STL、推薦學習)題解與代碼

比賽地址&#xff1a;https://www.starrycoding.com/contest/8 題目描述 在上一場的入門教育賽中&#xff0c;牢 e e e找到了所有自助店的位置&#xff0c;但是他想發現一些“高分好店”&#xff0c;于是他利用爬蟲技術從“小眾點評APP”中爬取了武漢所有自助店的評分。 評分…

Python 機器學習 基礎 之 構建第一個機器學習應用

Python 機器學習 基礎 之 構建第一個機器學習應用 目錄 Python 機器學習 基礎 之 構建第一個機器學習應用 一、簡單介紹 二、第一個機器學習測試應用介紹&#xff1a;鳶尾花分類 三、第一個機器學習測試應用 &#xff1a;前置環境&#xff0c;知識點介紹 jupyter notebo…

mamba-ssm安裝卡著不動

項目中用到Mamba的小伙伴&#xff0c;causal_conv1d和 mamba-ssm兩個包&#xff0c;但是會卡在Building wheel for mamba-ssm (setup.py) &#xff1a; 為了探究卡在了building的哪一步&#xff0c;加入–verbose進行顯示&#xff1a; pip install mamba-ssm --no-cache-dir -…

Linux 安裝JDK和Idea

安裝JDK 下載安裝包 下載地址&#xff1a; Java Downloads | Oracle (1) 使用xshell 上傳JDK到虛擬機 (2) 移動JDK 包到/opt/environment cd ~ cd /opt sudo mkdir environment # 在 /opt下創建一個environment文件夾 ls# 復制JDK包dao /opt/environment下 cd 下載 ls jd…

openGauss學習筆記-279 openGauss性能調優-實際調優案例08-改寫SQL消除in-clause

文章目錄 openGauss學習筆記-279 openGauss性能調優-實際調優案例08-改寫SQL消除in-clause279.1 現象描述279.2 優化說明openGauss學習筆記-279 openGauss性能調優-實際調優案例08-改寫SQL消除in-clause 279.1 現象描述 in-clause/any-clause是常見的SQL語句約束條件,有時in…