NSArray的sorting排序

       NSArray的排序用的挺多的,但是方法挺簡單的,大概是因爲ios方法本身封裝好了,不需我們考慮算法的問題,只管調用就好了。

1、基本的3種:

1) - (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context ;

2)- (NSArray *)sortedArrayUsingSelector:(SEL)comparator ;

3)- (NSArray *)sortedArrayUsingComparator:(NSComparator)cmptr ;

 3者在內容上其實沒有什麼差別,只是一個是用C函數,一個是OC方法,還一個是使用block;使用sortedArrayUsingComparator:的例子:

<span style="font-size:18px;">NSArray * integerArr = @[@68,@3,@24,@8,@110];
    NSArray * sortedArr = [integerArr sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        if ([obj1 integerValue]>[obj2 integerValue]) {
            return (NSComparisonResult)NSOrderedDescending;
        }else{
            return (NSComparisonResult)NSOrderedAscending;
        }
    }];
</span>
  需要注意的是返回的值是 NSComparisonResult枚舉類型,而且如果像例子裏面這樣寫,排序後是升序的,具體怎麼實現的不清楚。如果按冒泡排序法的角度去理解,貌似返回值是NSOrderedDescending的時候,會調換兩個值的位置,返回NSOrderedAscending則保持他們的順序。這樣去理解上的例子,在obj1>obj2時,會調換他們位置,然後變成小的在前大的在後,而obj2<obj1時,不調換順序,則依然保持小的在前大的在後的狀態, 如果相等,調換或不調換都一樣。

  這樣進行排序的好處是,不僅僅可以比較傳入的obj1\obj2本身,假如他們是自定義的對象,比如學生,然後這個對象有個屬性是數字、字符串或日期類型,比如學生的年齡,就可以比較這些,這樣可以通過屬性的大小的進行排序。在網上商城裏面搜索物品,都有多種排序方式,比如價格、銷量、好評等等,雖然這些數據可能是從後臺直接得到,app本身也可能需要排序,這時通過屬性進行排序就有用了。

 對於- (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context ;稍有特別的是,因爲在排序的時候,C函數是系統去調用的,參數也是系統傳遞的,如果自己想傳入一些特別的參數用於幫助排序,可以給方法裏面的context賦值,這個變量會傳遞給用於排序的C函數。

  2、更簡潔的:

- (NSArray *)sortedArrayUsingDescriptors:(NSArray *)sortDescriptors,只需提供一個NSSortDescriptor對象的數組

<span style="font-size:18px;">-(void)sortArr2{
    NSArray * integerArr = @[@"wde",@"wefs",@"aihfk3iu2q",@"ahhdiqediuehuhe",@"hdhhaniwhidklahidhd"];
    NSSortDescriptor * sort = [[NSSortDescriptor alloc]initWithKey:nil ascending:YES];
    NSArray * sortedArr = [integerArr sortedArrayUsingDescriptors:@[sort]];
    NSLog(@"%@",sortedArr);
}</span><span style="font-size:14px;">
</span>

NSSortDescriptor 構建的時候的key是進行排序的東西,當傳入爲nil的時候,會比較數組裏面的對象本身,上面的例子中就是比較各個字符串的大小,結果就是:

<span style="font-size:14px;">2014-08-07 11:00:50.183 compare_Demo[1302:70b] (
    ahhdiqediuehuhe,
    aihfk3iu2q,
    hdhhaniwhidklahidhd,
    wde,
    wefs
)</span>
如果傳入key,就會對數組裏面的每個對象進行valueForKey:取值,然後比較這個值,改爲:

<span style="font-size:18px;">NSSortDescriptor * sort = [[NSSortDescriptor alloc]initWithKey:@"length" ascending:YES];</span>
之後,結果就是:

<span style="font-size:18px;">2014-08-07 11:04:53.753 compare_Demo[1320:70b] (
    wde,
    wefs,
    aihfk3iu2q,
    ahhdiqediuehuhe,
    hdhhaniwhidklahidhd
)</span><span style="font-size:14px;">
</span>
也就是按字符串的長度來排序。

第二個參數是一個BOOL值,YES爲升序,NO爲降序。使用這個方法更爲簡潔,但是限制於比較的方法是系統本身的,和之前的幾個方法不同,比較的對象該是NSNumber、NSString、NSDate之類的系統能夠直接比較大小的類的對象。

3、一個特殊的方法:

- (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context hint:(NSData *)hint

這裏面有一個參數hint,看了文檔和網上的資料。這個方法是使用於這樣的情形的:當你對一個較大的數組(Arr)進行排序之後(sortedArr1),你對這個數組做了幾個元素的修改(被修改的元素數遠小於總元素數)(sortedArr2),這個數組不再是排好序的,但接近排好序的狀態,然後可以使用這個方法來快速的完成再次排序。

 首先需要之前排好序的數組sortedArr1調用- (NSData *)sortedArrayHint得到hint對象,用於上面的排序方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章