前言:
今天看到同事寫的一段排序代碼,我第一反應(yīng)是如果是當(dāng)前這種需求,我不會這樣寫,同時,我又在想他這樣寫是不是有別的意圖,這種寫法有什么好處,還有沒有其他方法可以實現(xiàn),于是就有了這篇文章
//按字母順序排序 - 升序
//同事寫法
NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [obj1 compare:obj2];
}];
//我會這樣寫 - 相信大多數(shù)人都會這樣寫
NSArray *sortedArray = [keys sortedArrayUsingSelector:@selector(compare:)];
正文:
首先確定你要比較的元素是同一類型,不然程序會crash
;
這里只講不可變數(shù)組的排序,可變數(shù)組的排序原理一樣,方法名不同而已;
1. 先來介紹一下- (NSArray *)sortedArrayUsingSelector:(SEL)comparator
; 返回一個數(shù)組,并通過給定的比較方法來接收排序后的元素
1.1 如果后面的selector
為compare:
則默認(rèn)升序排序,適用于數(shù)組內(nèi)元素為簡單類型的排序,如:字符串、基本數(shù)字類型。如果是字符串類型,則會從第一個字符開始依次比較;數(shù)字類型則直接比較大小,比較簡單,這里不再演示;
NSArray *arr1 = @[@"lucy",@"2tom",@"lykk",@"john",@"marry"];
//升序
NSArray *result1 = [arr1 sortedArrayUsingSelector:@selector(compare:)];
NSLog(@"升序 = %@",result1);
//當(dāng)然先這樣實現(xiàn)了升序,但你想要降序,怎么辦?
//倒序輸出 -> 得到降序數(shù)組
result1 = [[result1 reverseObjectEnumerator] allObjects];
NSLog(@"降序 = %@",result1);
1.2 如果后面的selector
為自定義方法,適用于復(fù)雜對象的排序,這里我定義一個學(xué)生對象,個人覺得該方法稍麻煩,實際開發(fā)中使用不多。
首先需要去對象的.h
文件去聲明排序方法,并去.m
文件目錄下實現(xiàn)下。
注意:這里還有一種情況,就是比較的這兩個元素相等時,這個排序的順序是怎樣的?
我修改了上面stu
隊列的兩個地方:
① 將stu4
的age
更改為20
;
② 改變stu4
在原數(shù)組中的位置,下標(biāo)由3
變?yōu)?code>1;
我們再來看一下按age
排的結(jié)果:
我們可以看到
Tom
和john
的age
一樣,但是Tom
排在了john
的前面,原因是Tom
在原始隊列中的位置比john
靠前。但是Tom
原來的下標(biāo)為1
,現(xiàn)在變成了2
,可見指定排序規(guī)則的優(yōu)先級最高,如果出現(xiàn)比較元素相等的情況,系統(tǒng)才會默認(rèn)比較原始下標(biāo)。這讓我想到了上學(xué)時班里的成績表,明明我和好幾個同學(xué)的成績一樣,可可為什么我排在了最后面?:
① 當(dāng)成績一樣之后,排名軟件沒做處理,默認(rèn)根據(jù)原始隊列下標(biāo)排序;
② 也可能增加一條比較規(guī)則,再根據(jù)姓名比較/根據(jù)學(xué)號比較;
③ 也可能會出現(xiàn)姓名一樣的情況,這時候再定義一條規(guī)則,根據(jù)學(xué)號來比較(其實這里比較完成績后再根據(jù)學(xué)號比較好,學(xué)號一般在一個學(xué)校里是唯一的)代碼中具體怎么加規(guī)則,下面會提到
2. 接下來我們來介紹一下我同事使用的那種排序方法sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) { }];
這是Xcode 4
之后出的一個比較好用的一個排序方法,不像自定義排序方法那樣麻煩,個人建議在開發(fā)中復(fù)雜類型的排序用這種方法。
2.1 對簡單類型進(jìn)行排序
2.2 對復(fù)雜對象進(jìn)行排序
3. 高級排序:按描述進(jìn)行排序(制定一套排序規(guī)則 )
4. 總結(jié):
上述簡單的介紹了幾種在OC
中排序的方法,有紕漏之處還請大家指出,后續(xù)有時間再補充其他排序方法;當(dāng)然使用冒泡排序/選擇排序等也可以實現(xiàn)上述排序,這里不再代碼演示。