按照NSArray內部的某個物件排序
stackoverflow上關於Objective-C關注度比較高的問題系列
連結
按照NSArray內部的某個物件排序
原文連結How do I sort an NSMutableArray with custom objects in it?
本文Github連結
關鍵詞
Sort
NSArray
NSSortDescriptor
我想實現的事情看起來很簡單,但在網上卻找不到答案。有一個NSMutableArray
or NSArray
陣列,陣列中的元素是Person
物件。我想按照Person.birthDate
來排序,birthDate
的型別是NSDate
。
我猜測實現的方式的虛擬碼應該如下:
NSArray *sortedArray = [drinkDetails sortedArrayUsingSelector:@selecrot(???)];
排序方法
1) 物件中實現Compare方法(Compare method)
首先,在Person的implementation中實現 compare
method:
- (NSComparisonResult)compare:(Person *)person {
return [self.birthDate compare:person.birthDate];
}
然後在需要排序的地方呼叫- (NSArray<ObjectType> *)sortedArrayUsingSelector:(SEL)comparator
。
NSArray *sortedArray = [array sortedArrayUsingSelector:@selector(compare:)];
2)NSSortDescriptor
NSSortDescriptor
的key
屬性為需要排序物件的某個屬性(此處用到了KVC);ascending
用於指定升序還是降序,YES-> 生序,NO->降序 ``
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"birthDate" ascending:YES];
NSSortDescriptor *nameSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSArray *sortDescriptors = @[sortDescriptor,nameSortDescriptor];
NSArray *sortedArray = [array sortedArrayUsingDescriptors:sortDescriptors];
通過向array增加不同的key,可以很輕鬆的實現多個key複合排序(此處的複合排序指:當第一個標準的兩個值相同時,此時需要第二個標準來參與排序,第二個標準也相同的話就需要引入第三個標準,以此類推)。
優先比較sortDescriptors的第一項,然後第二項,然後第三項,以此類推。
關於NSSortDescriptor可參考檔案
3) Blocks
Mac OS X 10.6 和 iOS4之後也可以使用block來排序:
NSComparator sortComparator = ^NSComparisonResult(id a, id b) {
NSDate *first = [(Person *)a birthDate];
NSDate *second = [(Person *)b birthDate];
return [first compare:second];
};
NSArray *sortedArray = [array sortedArrayUsingComparator:sortComparator];
一般來說,基於block和-compare:
的方法實現起來會比使用NSSortDescriptor
稍微快一點,後者是依賴於KVC
。NSSortDescriptor
的主要優勢在於它可以直接使用資料來定義排序的標準即可,不需要自己來寫排序。在上一個例子中,只需要指定key
和是否為升序
兩個引數就可以排序了,block方法還需要自己來compare first
and second
。
當然在compare first
和second
的時候再複雜一些,比較一下Person的其他屬性也能達到NSSortDescriptor的複合排序。
結果及分析
我將以上三種方法各執行一次得到的三次結果如下:
1)物件中實現Compare方法(Compare method)
original array:
name: birthDate: age:
Jixin 1526984251.000000 14
Alex 1526923252.000000 22
alex 1527983288.000000 21
Chandler 1527983288.000000 23
Kobe 1526083230.000000 24
1Day 1426983253.000000 7
-----------------------
1. 物件中實現Compare方法:
sorted array:
name: birthDate: age:
1Day 1426983253.000000 7
Kobe 1526083230.000000 24
Alex 1526923252.000000 22
Jixin 1526984251.000000 14
alex 1527983288.000000 21
Chandler 1527983288.000000 23
-----------------------
duration = 0.000061
Program ended with exit code: 0
分析結果
- 最終陣列的順序是按照
birthDate
的由小到大排序; - 最後兩個資料的
birthDate
相同卻沒有按照name
的升序排列; - 程式碼執行時間duration = 0.000061。
注:在ASCII碼中小寫字母是排在大寫字母后面的。字母a
對應的十進位制數是97,字母A
對應的十進位制數是65,字母C
(此處C大寫)對應的十進位制數是67)。
2)NSSortDescriptor
original array:
name: birthDate: age:
Jixin 1526984251.000000 25
Alex 1526923252.000000 1
alex 1527983288.000000 12
Chandler 1527983288.000000 21
Kobe 1526083230.000000 6
1Day 1426983253.000000 4
-----------------------
2. NSSortDescriptor方法:
sorted array:
name: birthDate: age:
1Day 1426983253.000000 4
Kobe 1526083230.000000 6
Alex 1526923252.000000 1
Jixin 1526984251.000000 25
Chandler 1527983288.000000 21
alex 1527983288.000000 12
-----------------------
duration = 0.000341
Program ended with exit code: 0
分析結果
- 最終陣列的順序是按照
birthDate
的由小到大排序; - 最後兩個資料的
birthDate
相同,然後按照name
的升序排列。 - 程式碼執行時間duration = 0.000341。
3)Blocks
original array:
name: birthDate: age:
Jixin 1526984251.000000 21
Alex 1526923252.000000 23
alex 1527983288.000000 12
Chandler 1527983288.000000 3
Kobe 1526083230.000000 27
1Day 1426983253.000000 12
-----------------------
3. Block方法:
sorted array:
name: birthDate: age:
1Day 1426983253.000000 12
Kobe 1526083230.000000 27
Alex 1526923252.000000 23
Jixin 1526984251.000000 21
alex 1527983288.000000 12
Chandler 1527983288.000000 3
-----------------------
duration = 0.000062
Program ended with exit code: 0
分析結果
- 最終陣列的順序是按照
birthDate
的由小到大排序; - 最後兩個資料的
birthDate
相同卻沒有按照name
的升序排列; - 程式碼執行時間duration = 0.000062。
4)效能分析
在計算duration的時候,不同電腦,得到的結果是不一樣的,但是數字對應的數量級應該是一致的。
三次的時間分別如下:
- duration = 0.000061
- duration = 0.000341
- duration = 0.000062
可以看出前方法1和3的在同一個數量級上,第二種方法明顯其他兩種大一個數量級。
我們利用for迴圈將每部分程式碼執行1,000,000次,得到的結果如下:
- duration = 1.128369
- duration = 3.287778
- duration = 1.433518
依然可以得到相同的結果。1秒和3秒之間的差距,感知是很明顯的。
5)結論
- 如果沒有複合排序,可優先選擇block方法。程式碼較為集中看起來邏輯較清晰;
- 如果有複合排序,資料量不大的時候可以使用NSSortDescriptor;資料量較大時建議選擇block方法。
相關文章
- 二維陣列按照其內層陣列的某個鍵值排序陣列排序
- 陣列物件按物件某個屬性排序陣列物件排序
- iOS中對NSArray中自定義的物件進行排序iOS物件排序
- 「Js」物件按照鍵名來進行排序JS物件排序
- Js實現Object按照值的某個欄位(數值型別)的大小進行排序JSObject型別排序
- JAVA裡List集合中的物件根據物件的某個屬性值降序或者升序排序Java物件排序
- JavaScript內部物件和Date物件JavaScript物件
- 按照價格排序!排序
- nest loop內層迴圈會按照rowid排序嗎?OOP排序
- MySQL排序內部原理探祕MySql排序
- MySQL 按照指定的欄位排序MySql排序
- 【筆記】內部排序演算法筆記排序演算法
- 內部排序分類及穩定性排序
- 物件導向之內部類物件
- mysql資料表按照某個欄位分類輸出MySql
- Oracle自定義函式---按照某個分隔符拆分字串Oracle函式字串
- 讓 排序 按照 in 列表的的顯示順序排序輸出。排序
- 非k8s環境下,進入docker某個容器內部K8SDocker
- Elasticsearch 按照標籤匹配個數優先排序查詢Elasticsearch排序
- 逆向工程通過某個欄位排序排序
- js 取陣列中某個物件的集合JS陣列物件
- dedecms標籤按照權重排序排序
- js 漢字按照拼音排序效果JS排序
- sort按照數值大小排序排序
- Js陣列物件的屬性值升序排序,並指定陣列中的某個物件移動到陣列的最前面JS陣列物件排序
- PHP 多維陣列排序-按某個 key 的值PHP陣列排序
- 小談java內部類物件的生成過程Java物件
- Python 內部:可呼叫物件是如何工作的Python物件
- 反射-通過反射寫一個通用的設定某個物件的某個屬性為指定的值反射物件
- java8的stream將一個List轉為按照某個欄位分組的map,再按照另一個欄位取max最終得到一個mapJava
- 大模型內部有一個平面和直邊構成的幾何物件大模型物件
- 獲取某庫某個儲存過程內容儲存過程
- thinkphp where in order 按照順序in的迴圈排序PHP排序
- PHP 字串陣列按照拼音排序的問題PHP字串陣列排序
- C#獲取某個物件的屬性值C#物件
- 監聽某個物件事件的幾種方法物件事件
- Redis 物件內部組織結構 —— 字典Redis物件
- 物件導向--內部屬性型別物件型別