版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2017.08.25 |
前言
NSArray
是集合類型中的一種,是OC中很重要的概念,這個是我們一定會用到的對象,下面我就繼續由整體到細節,由簡單到復雜的和大家說一下它的用法。感興趣的可以看我寫的上篇幾篇。
1. NSArray簡單細說(一)—— 整體了解
2. NSArray簡單細說(二)—— 數組的創建
3. NSArray簡單細說(三)—— 數組初始化
4. NSArray簡單細說(四)—— 數組的查詢與檢索
5. NSArray簡單細說(五)—— 數組中對象的查找
6. NSArray簡單細說(六)—— 向數組中元素發送消息
7. NSArray簡單細說(七)—— 數組的比較和獲得新數組
一、@property(readonly, copy) NSData *sortedArrayHint;
該屬性的作用就是:分析數組,并返回一個hint
,當hint
參數傳遞給sortedArrayUsingFunction: context:hint :
時,可以加快數組的排序,上面調用的就是這個函數。
- (NSArray<ObjectType> *)sortedArrayUsingFunction:(NSInteger (*)(ObjectType, ObjectType, void *))comparator context:(void *)context hint:(NSData *)hint;
上面這個方法如何使用這里就不多說了,后面會和大家細說,下面我們看一下代碼。
- (void)demoSortedArrayHint
{
NSArray *arr = @[@1, @2, @3];
NSData *data = [arr sortedArrayHint];
NSLog(@"%@", data);
}
下面看輸出結果
2017-08-25 21:13:01.514 JJOC[6905:176200] <b179379e 62f36e3c 136da6da>
這個大家是看不懂的,都是十六進制數據,后面會詳細的和大家說的。
結論:不怎么用,但是還是要了解下。
二、- (NSArray<ObjectType> )sortedArrayUsingFunction:(NSInteger ()(ObjectType, ObjectType, void *))comparator context:(void *)context;
該方法的作用就是:返回一個新的數組,該數組是按照比較函數比較器定義的升序排列的。
還有一點需要注意:
新數組包含對接收數組元素的引用,而不是它們的副本。比較函數用于一次比較兩個元素,如果第一個元素小于第二個元素,則返回
NSOrderedAscending
,如果第一個元素大于第二個元素則返回NSOrderedDescending
,如果元素相等則返回NSOrderedSame
。 每次調用比較函數時,它將上下文作為第三個參數傳遞。 這允許比較基于一些外部參數,例如字符排序是區分大小寫還是不區分大小寫。給定一個
Array
(一個NSNumber對象的數組)和一個這種類型的比較函數,下面看代碼
NSInteger 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;
}
以這種方式創建Array的排序:
NSArray *sortedArray;
sortedArray = [anArray sortedArrayUsingFunction:intSort context:NULL];
結論:還算好理解。
三、- (NSArray<ObjectType> )sortedArrayUsingFunction:(NSInteger ()(ObjectType, ObjectType, void *))comparator context:(void *)context hint:(NSData *)hint;
該方法的作用就是:返回一個新數組,按照比較函數比較器定義的升序列出接收數組的元素。
還有幾點需要注意:
- 新數組包含對接收數組元素的引用,而不是它們的副本。此方法類似于
sortedArrayUsingFunction:context:
,除了它使用提供的提示來加快排序過程。 當你知道數組幾乎被排序時,這個方法比sortedArrayUsingFunction:context:
更快。 如果您排序了一個大數組(N個條目)一次,并且不會更改它(P的添加和刪除,P小于N),那么您可以通過概念上的方式重用您在原始排序中所做的工作 N個“舊”項目和P“新”項目之間的合并排序。 - 要獲得適當的提示,請使用
sortedArrayHint
。 當原始數組被排序后,您應該獲取此提示,并在數組修改后保持該提示,直到需要它。 提示由O(N)
中的sortedArrayHint
計算(其中N是項目數)。 這假設數組中的項目實現了-hash
方法。 給定一個合適的提示,并假設散列函數是一個“好”散列函數,-sortedArrayUsingFunction:context:hint:
在O(P * LOG(P)+ N)
中對數組進行排序,其中P是添加或刪除的數量。 當P較小時,這是一個非暗示類型O(N * LOG(N))
的改進。 - 提示只是一個包含N個哈希值的大小為N的數組。 要重新排序,您需要在內部創建映射表,將散列映射到索引。 在新數組中使用此映射表,您可以首先猜出索引,然后進行排序。 例如,具有相應散列值
{25,96,78,32,17}
的排序數組{A,B,D,E,F}
可能經受小的變化,導致內容{E,A,C, B,F}
。 映射表將散列{25,96,78,32,17}
映射到索引{#0,#1,#2,#3,#4}
。 如果{E,A,C,B,F}
的散列是{32,25,99,96,17}
,那么通過使用映射表,您可以得到第一個排序{#3,#0,?, #1,#4}
,因此創建一個初始半排序數組{A,B,E,F}
,然后用{ C }
執行便宜的合并排序,得到{A,B,C,E,F}
。
結論:這個確實需要好好的理解一下,有點設計算法的底層了。
四、- (NSArray<ObjectType> *)sortedArrayUsingDescriptors:(NSArray<NSSortDescriptor *> *)sortDescriptors;
該方法的作用就是:返回由給定的排序描述符數組指定的接收數組的副本。
下面我們就看一下參數和返回值:
-
sortDescriptors
:NSSortDescriptor
對象的數組。 -
return
:按sortDescriptors
指定排序的接收數組的副本。
還有幾點需要注意:
- 第一個描述符指定在對接收數組的內容進行排序時使用的主鍵路徑。 任何后續描述符用于進一步改進具有重復值的對象的排序。 有關其他信息,請參閱
NSSortDescriptor
。
下面我們看一下代碼
- (void)demoSortedArrayUsingDescriptors
{
NSDictionary *dic1 = [NSDictionary dictionaryWithObjectsAndKeys:@"2030",@"year", @"1",@"month",nil];
NSDictionary *dic2 = [NSDictionary dictionaryWithObjectsAndKeys:@"2010",@"year", @"2",@"month", nil];
NSDictionary *dic3 = [NSDictionary dictionaryWithObjectsAndKeys:@"2050",@"year", @"3",@"month" ,nil];
NSDictionary *dic4 = [NSDictionary dictionaryWithObjectsAndKeys:@"2014",@"year", @"4",@"month",nil];
NSDictionary *dic5 = [NSDictionary dictionaryWithObjectsAndKeys:@"2050",@"year", @"4",@"month",nil];
NSArray *array = [NSArray arrayWithObjects:dic1, dic2, dic3, dic4, dic5, nil];
NSSortDescriptor *descripor = [NSSortDescriptor sortDescriptorWithKey:@"year" ascending:NO];
NSSortDescriptor *descripor2 = [NSSortDescriptor sortDescriptorWithKey:@"month" ascending:NO];
NSArray *resultArr = [array sortedArrayUsingDescriptors:[NSArray arrayWithObjects:descripor, descripor2, nil]];
NSLog(@"resultArr = %@", resultArr);
}
下面我們看一下輸出結果
2017-08-25 22:35:36.342 JJOC[8148:226465] resultArr = (
{
month = 4;
year = 2050;
},
{
month = 3;
year = 2050;
},
{
month = 1;
year = 2030;
},
{
month = 4;
year = 2014;
},
{
month = 2;
year = 2010;
}
)
結論:這個還是經常會用到的,大家需要好好看看。
五、- (NSArray<ObjectType> *)sortedArrayUsingSelector:(SEL)comparator;
該方法的作用是:返回一個數組,按照由給定選擇器指定的比較方法確定的升序列出接收數組的元素。
下面看一下參數和返回值:
-
comparator
:標識用于一次比較兩個元素的方法的選擇器。 如果接收數組小于參數,則該方法應返回NSOrderedAscending
,如果接收數組大于參數,NSOrderedDescending
,如果相等則為NSOrderedSame
。 -
return
:一個數組,由選擇器比較器指定的比較方法確定,按照升序排列接收數組的元素。
還有幾點需要注意:
- 新數組包含對接收數組元素的引用,而不是它們的副本。
比較器消息被發送到數組中的每個對象,并且在數組中具有另一個對象。例如,NSString對象的數組可以使用在NSString類中聲明的caseInsensitiveCompare:
方法進行排序。 假設存在anArray,則可以按以下方式創建數組的排序方式:
NSArray *sortedArray = [anArray sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
下面看完整代碼
- (void)demoSortedArrayUsingSelector
{
NSArray *arr = @[@"hello", @"how", @"are", @"you"];
NSArray *resultArr = [arr sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
NSLog(@"resultArr = %@", resultArr);
}
下面看輸出結果
2017-08-25 22:59:07.430 JJOC[8986:249270] resultArr = (
are,
hello,
how,
you
)
結論:這個方法還是挺有意思的。
六、- (NSArray<ObjectType> *)sortedArrayUsingComparator:(NSComparator)cmptr;
該方法的作用就是:返回一個數組,按照由給定的NSComparator
塊指定的比較方法確定的升序列出接收數組的元素。
對于返回值,就是一個數組,按照指定的cmptr的比較方法,按升序列出接收數組的元素。
下面我們就看一下代碼
- (void)demoSortedArrayUsingComparator
{
NSArray *arr = @[@"hello", @"how", @"are", @"you"];
NSArray *resultArr = [arr sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
return [obj1 compare:obj2];
}];
NSLog(@"resultArr = %@", resultArr);
}
下面看輸出結果
2017-08-25 23:10:48.071 JJOC[9363:257667] resultArr = (
are,
hello,
how,
you
)
上面這個就是按照升序進行排列的,那么按照降序呢,可以進行如下修改:
[obj2 compare:obj1];
下面看輸出結果
2017-08-25 23:12:02.545 JJOC[9490:259440] resultArr = (
you,
how,
hello,
are
)
結論:這個總會用到,好好理解下就可以了,不難的。
七、- (NSArray<ObjectType> *)sortedArrayWithOptions:(NSSortOptions)opts usingComparator:(NSComparator)cmptr;
該方法的作用就是:返回一個數組,按照由給定的NSComparator塊指定的比較方法確定的升序列出接收數組的元素。
下面我們看一下參數和返回值:
-
opts
:指定排序選項的位掩碼(是否應同時執行以及是否應穩定執行)。這里是一個枚舉,如下所示。
typedef NS_OPTIONS(NSUInteger, NSSortOptions) {
NSSortConcurrent = (1UL << 0),
NSSortStable = (1UL << 4),
};
-
cmptr
:比較器的代碼塊。 -
return
:一個數組,按照指定的cmptr
的比較方法,按升序列出接收數組的元素。
下面我們看代碼
- (void)demoSortedArrayWithOptions
{
NSArray *arr = @[@"6", @"9", @"2", @"1"];
NSArray *resultArr = [arr sortedArrayWithOptions:NSSortConcurrent usingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
return [obj1 compare:obj2];
}];
NSLog(@"resultArr = %@", resultArr);
}
下面看輸出結果
2017-08-25 23:20:22.843 JJOC[9834:267493] resultArr = (
1,
2,
6,
9
)
結論:結合代碼看,很好理解。
后記
未完,待續~~~