3C科技 娛樂遊戲 美食旅遊 時尚美妝 親子育兒 生活休閒 金融理財 健康運動 寰宇綜合

Zi 字媒體

2017-07-25T20:27:27+00:00
加入好友
相信如果你是 iOS 的程式設計師,一定都有使用過 NSArray 這個非常基本的元件,而大多數的程式設計師,在使用 NSArray 時,都會使用到排序的功能,而排序不外乎就是使用「sortedArrayUsingComparator」和「NSComparisonResult」的且合方式,但如果有多個條件要同時排序,這可就頭大了!幸好 iOS 提供了另一種陣列排序的方式,叫做「sortedArrayUsingDescriptors」,怎麼用呢?先別急,我們先看範例。   舉例來說,我們有一個物件,叫做「Person」,宣告如下: @interface Person : NSObject   @property (strong, nonatomic) NSString* name; @property (assign, nonatomic) int age; @property (assign, nonatomic) int income;   @end   而接下來,我們分別宣告三個人,並把他們三個人加入陣列中,如下 Person *A = [[Person alloc] init]; A.name = @"孫無空"; A.age = 33; A.income = 50;   Person *B = [[Person alloc] init]; B.name = @"唐三"; B.age = 43; B.income = 55;   Person *C = [[Person alloc] init]; C.name = @"沙無淨"; C.age = 33; C.income = 60;   NSMutableArray* unSortArray = [NSMutableArray arrayWithObjects:A,B,C, nil];   假設,我們要以「收入(income)」做為排序,收入愈高的排愈前面,怎麼排呢?很簡單,只要寫這樣~~ Person *A = [[Person alloc] init]; A.name = @"孫無空"; A.age = 33; A.income = 50;   Person *B = [[Person alloc] init]; B.name = @"唐三"; B.age = 43; B.income = 55;   Person *C = [[Person alloc] init]; C.name = @"沙無淨"; C.age = 33; C.income = 60;   NSMutableArray* unSortArray = [NSMutableArray arrayWithObjects:A,B,C, nil];   NSComparator compare = ^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) { NSString* strObj1 = (NSString*) obj1; NSString* strObj2 = (NSString*) obj2; NSNumber* number1 = @([strObj1 doubleValue]); NSNumber* number2 = @([strObj2 doubleValue]);   return [number1 compare: number2]; };   NSMutableArray* arraySortCondtion = [[NSMutableArray alloc] init]; [arraySortCondtion addObject: [NSSortDescriptor sortDescriptorWithKey:@"sortcond_income" ascending:NO comparator: compare]]; NSArray* sortArray = [unSortArray sortedArrayUsingDescriptors: arraySortCondtion];   其中最重要的就是「sortedArrayUsingDescriptors」了,首先你要定義 Sort 的 Key,由於我們是依收入排序,所以我們定義「sortcond_income」;再來,由於我們是採用降冪排序,也就是收入高的在前面,所以在這裡「ascending」要設為 NO,最後就是你自己定義的 compare 函式了。 但是,代誌沒有你我想的這麼簡單,如果真的這樣排,會出錯,為什麼呢?因為在「Person」物件不認識「sortcond_income」這個 key 呀!所以我們要改寫一下 Person 物件,加入了「valueForUndefinedKey」。如此一來,當我們去抓 sortcond_income 時,就會把 income 轉成 NSString 來匯出了。 @implementation Person   - (id)valueForUndefinedKey:(NSString *)key { if ([key isEqualToString:@"sortcond_income"]) { return [@(self.income) stringValue]; }   return [super valueForUndefinedKey:key]; }   @end   如果你依以上的排序方式實做一次,那麼最後的結果依序就是「沙無淨」、「唐三」、「孫無空」了。 但是,如果我們想要一次排多個條件呢?比如說這次採用「年齡升冪」排序,若是同樣的年齡,再採用「收入降冪」排序,那麼將如何寫呢?很簡單~~ Person *A = [[Person alloc] init]; A.name = @"孫無空"; A.age = 33; A.income = 50;   Person *B = [[Person alloc] init]; B.name = @"唐三"; B.age = 43; B.income = 55;   Person *C = [[Person alloc] init]; C.name = @"沙無淨"; C.age = 33; C.income = 60;   NSMutableArray* unSortArray = [NSMutableArray arrayWithObjects:A,B,C, nil];   NSComparator compare = ^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) { NSString* strObj1 = (NSString*) obj1; NSString* strObj2 = (NSString*) obj2; NSNumber* number1 = @([strObj1 doubleValue]); NSNumber* number2 = @([strObj2 doubleValue]);   return [number1 compare: number2]; }; NSMutableArray* arraySortCondtion = [[NSMutableArray alloc] init]; [arraySortCondtion addObject: [NSSortDescriptor sortDescriptorWithKey:@"sortcond_age" ascending:YES comparator: compare]]; [arraySortCondtion addObject: [NSSortDescriptor sortDescriptorWithKey:@"sortcond_income" ascending:NO comparator: compare]]; NSArray* sortArray = [unSortArray sortedArrayUsingDescriptors: arraySortCondtion];   看到沒有,我們只不過多加了一行程式碼就完成了,而這行程式碼如下 [arraySortCondtion addObject: [NSSortDescriptor sortDescriptorWithKey:@"sortcond_age" ascending:YES comparator: compare]];   同樣的,一樣要在 Person 物件定義「sortcond_age」喔 @implementation Person   - (id)valueForUndefinedKey:(NSString *)key { if ([key isEqualToString:@"sortcond_income"]) { return [@(self.income) stringValue]; } if ([key isEqualToString:@"sortcond_age"]) { return [@(_age) stringValue]; } return [super valueForUndefinedKey:key]; }   @end 如果你依以上的排序方式實做一次,那麼最後的結果依序就是「沙無淨」、「孫無空」、「唐三」了。為什麼呢?因為「沙無淨」、「孫無空」的「年齡 (age) 」是一樣的,所以會依第二個條件「收入(income)」來做降冪排序,「沙無淨」的收入大於「孫無空」,所以自然就擺在「孫無空」 前面了,而可憐的「唐三」因為「年齡 (age) 」最大,所以被丟到最後面啦~~   以上就是 iOS 的陣列排序介紹,是以 Objective-C 做描述,讀者有興趣可以自行轉成 Swift,希望您使用起來能夠輕鬆愉快囉~

本文由inote提供 原文連結

寫了 5860316篇文章,獲得 23313次喜歡
精彩推薦