iOS探索:對(duì)NSArray中自定義的對(duì)象進(jìn)行排序
本文譯自How to sort NSArray with custom objects。
我們開(kāi)發(fā)的每個(gè)程序都會(huì)使用到一些數(shù)據(jù),而這些數(shù)據(jù)一般被封裝在一個(gè)自定義的類中。例如一個(gè)音樂(lè)程序可能會(huì)有一個(gè)Song類,聊天程序則又一個(gè) Friend類,點(diǎn)菜程序會(huì)有一個(gè)Recipe類等。有時(shí)候我們希望在程序中顯示的列表數(shù)據(jù)是按照一定順序進(jìn)行排列的,本文我們就來(lái)看看在iOS中有哪些 方法可以對(duì)NSArray中的對(duì)象進(jìn)行排序。下面是目錄:
- 小引
- 使用NSComparator進(jìn)行排序
- 使用NSDescriptor進(jìn)行排序
- 使用selector進(jìn)行排序
小引
我們將要排序的對(duì)象是一個(gè)Persion類,如下定義:
- @interface Person : NSObject
- @property (nonatomic, copy) NSString *name;
- @property (nonatomic, copy) NSString *surname;
- @property (nonatomic, strong) NSDate *dateOfBirth;
- @end
而數(shù)組中包含如下內(nèi)容:
- Smith John 03/01/1984
- Andersen Jane 16/03/1979
- Clark Anne 13/09/1995
- Smith David 19/07/1981
- Johnson Rose 22/02/1989
使用NSComparator進(jìn)行排序
comparator實(shí)際上是用一個(gè)block對(duì)象作比較操作。它的定義如下所示:
- typedef NSComparisonResult (^NSComparator)(id obj1, id obj2);
上面的參數(shù)(obj1、obj2)就是我們將要做比較的對(duì)象。block返回的結(jié)果為NSComparisonResult類型來(lái)表示兩個(gè)對(duì)象的順序。
要對(duì)整個(gè)數(shù)組做排序,則需要使用NSArray的sortArrayUsingComparator:方法,如下代碼所示:
- NSArray *sortedArray = [self.persons sortedArrayUsingComparator:^NSComparisonResult(Person *p1, Person *p2){
- return [p1.surname compare:p2.surname];
- }];
最終排序的結(jié)果如下所示:
- Andersen Jane
- Clark Anne
- Johnson Rose
- Smith John
- Smith David
使用NSDescriptor進(jìn)行排序
Sort descriptor不僅可以用來(lái)對(duì)數(shù)組進(jìn)行排序,還能指定element在table view中的排序,以及Core Data中對(duì)fetch request返回的數(shù)據(jù)做排序處理。通過(guò)sort descriptor可以很方便的對(duì)數(shù)組進(jìn)行多個(gè)key的排序。下面來(lái)看看如何對(duì)我們的數(shù)組做surname排序,然后在進(jìn)行name排序:
- NSSortDescriptor *firstDescriptor = [[NSSortDescriptor alloc] initWithKey:@"surname" ascending:YES];
- NSSortDescriptor *secondDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
- NSArray *sortDescriptors = [NSArray arrayWithObjects:firstDescriptor, secondDescriptor, nil];
- NSArray *sortedArray = [self.persons sortedArrayUsingDescriptors:sortDescriptors];
上面代碼的排序結(jié)果如下所示:
- Andersen Jane
- Clark Anne
- Johnson Rose
- Smith David
- Smith John
使用selector進(jìn)行排序
當(dāng)面,我們也可以定義自己的方法進(jìn)行兩個(gè)對(duì)象做比較,并將該方法用于數(shù)組排序。comparator消息會(huì)被發(fā)送到數(shù)值中的每個(gè)對(duì)象中,并攜帶數(shù)組中另外的一個(gè)對(duì)象當(dāng)做參數(shù)。自定義的的方法的返回結(jié)果是這樣的:如果本身對(duì)象小于參數(shù)中的對(duì)象,就返回NSOrederedAscending,相反,則返回NSOrderedDescending,如果相等,那么返回NSOrderedSame。如下代碼所示:
- - (NSComparisonResult)compare:(Person *)otherPerson {
- return [self.dateOfBirth compare:otherPerson.dateOfBirth];
- }
這個(gè)方法定義在Person類中,用來(lái)對(duì)person的生日進(jìn)行排序。
上面所介紹的這些方法都是為了完成相同的事情:對(duì)數(shù)組做排序處理,你可能在想改選擇使用哪個(gè)呢?當(dāng)需要通過(guò)多個(gè)key進(jìn)行排序,那么最簡(jiǎn)單的方法就 是使用sort descriptor。如果比較方法很復(fù)雜的話,建議在使用外面自己的selector。Block是再iOS 4之后引入的一個(gè)強(qiáng)大功能,用block作比較,可以不必使用任何的變量就能完成一個(gè)簡(jiǎn)單的比較方法,當(dāng)然,你也可以定義一個(gè)復(fù)雜的block,來(lái)替換 selector。
***,其實(shí)這里并沒(méi)有標(biāo)準(zhǔn)答案,你可以跟著自己的感覺(jué)走:]