2013-05-02 61 views
0

我有一個簡單的NSArray,其中包含NSNumber s。按升序對NSArray中的數字進行排序,但在末尾發送零。

我這樣排序按升序排列:

NSSortDescriptor *lowestToHighest = [NSSortDescriptor sortDescriptorWithKey:@"self" ascending:YES]; 
[_scores sortUsingDescriptors:[NSArray arrayWithObject:lowestToHighest]]; 

我的問題是,我想包含0是在末尾,而不是在開始NSNumber秒。這裏是我可能要排序的類型的數組(包含一些空NSNumber的只有我的例子):

0 
25 
12 
0 
8 
0 

我的課程的代碼進行排序的數組是這樣的:

0 
0 
0 
8 
12 
25 

我會就像是這樣的:

8 
12 
25 
0 
0 
0 

當然,我可以用0去除線,並在年底將他們重新排序它手動,但我在尋找最乾淨的小號解決方案可能。

+0

'8,12,0'是按升序還是降序排列?你是如何將'nil'存儲在'NSArray'中的?或者你確定你有'NSNumber'實例嗎?他們不是'NSString'嗎? – 2013-05-02 12:48:35

+0

@ H2CO3對作者如何在NSArray中表示NSNumber的方式設法存儲無值進行了約定 – 2013-05-02 12:50:16

+0

除了數值** 0 **之外,它是遞增順序,發送到數組的末尾。事實上,它們不是「零」對象,而是非初始化的NSNumbers。在調試控制檯中顯示爲** [5] id \t 0x00000000 ** – rdurand 2013-05-02 12:51:11

回答

13

排序使用comparator陣列。

NSArray *sortedArray = [array sortedArrayUsingComparator: ^(id obj1, id obj2) { 

    if ([obj1 integerValue] == 0 && [obj2 integerValue] == 0) 
    { 
     return (NSComparisonResult)NSOrderedSame; 
    } 
    if ([obj1 integerValue] == 0) 
    { 
     return (NSComparisonResult)NSOrderedDescending;    
    } 
    if ([obj2 integerValue] == 0) 
    { 
     return (NSComparisonResult)NSOrderedAscending; 
    } 

    if ([obj1 integerValue] > [obj2 integerValue]) 
    { 
     return (NSComparisonResult)NSOrderedDescending; 
    } 

    if ([obj1 integerValue] < [obj2 integerValue]) 
    { 
     return (NSComparisonResult)NSOrderedAscending; 
    } 
    return (NSComparisonResult)NSOrderedSame; 
}]; 
+0

看起來像我在找什麼..謝謝!我想過使用比較器,但無法使其工作。 – rdurand 2013-05-02 12:58:27

+0

沒有聲明這個代碼的部分 – 2015-05-19 08:51:40

+0

@gokhancokkececi你的意思是id1和id2 - 這顯然是一個錯字,現在已修復。 – JeremyP 2015-05-19 15:52:55

1

方法1:

  • 步驟1:對數組進行排序。

  • 第2步:將零移動到數組的末尾。

方法2:

  • 步驟1:寫一個比較器功能的訂單0之後任何其它值。

  • 第2步:對數組進行排序。

+0

謝謝,但那不是我要找的正如我在我的問題中所說的那樣。 – rdurand 2013-05-02 12:54:23

+0

@Monolo:當我發表我的評論時,Caleb只提出了第一種方法。我在我的問題中說過,我知道我可以做到這一點,但我一直在尋找比「排序然後移動零」更乾淨的東西。方法2正是JeremyP在他的回答中所說的,在迦勒編輯自己的答案之前出現了。 – rdurand 2013-05-02 13:10:42

4

這將解決您的問題,

NSArray *sortedScores = [_scores sortedArrayUsiHelperComparator:^(id obj1, id obj2){ 
    if([obj1 integerValue]==0 && [obj2 integerValue]==0){ 
     return (NSComparisonResult) NSOrderedSame; 
    }else if([obj1 integerValue]==0){ 
     return (NSComparisonResult) NSOrderedDescending; 
    }else if([obj2 integerValue]==0){ 
     return (NSComparisonResult) NSOrderedAscending; 
    } 
    if([obj1 integerValue] >[obj2 integerValue]) return (NSComparisonResult) NSOrderedDescending; 
    if([obj1 integerValue] <[obj2 integerValue]) return (NSComparisonResult) NSOrderedAscending; 
    return (NSComparisonResult) NSOrderedSame; 

}]; 
+0

謝謝,但我認爲JeremyP的回答更準確,因爲他比較* [id1 integerValue] == 0 *而不是* obj1 == nil *。在我的情況下,我想要零到最後,而不是零對象。 – rdurand 2013-05-02 12:57:17

+0

在你的問題中,有零值。我爲此編寫了代碼。你改變了這個問題。現在檢查! – 2013-05-02 12:59:55

+0

無論如何,你不能把'nil'放在'NSArray'中。 – JeremyP 2013-05-02 13:02:17

0

您可以使用NSPredicate過濾你不想要的值..

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self > 0"]; 
NSMutableArray *filteredArray = [[_scores filteredArrayUsingPredicate:predicate] mutableCopy]; 
NSSortDescriptor *lowestToHighest = [NSSortDescriptor sortDescriptorWithKey:@"self" ascending:YES]; 
[filteredArray sortUsingDescriptors:[NSArray arrayWithObject:lowestToHighest]]; 
+2

謝謝,但我相信這將刪除所有的零,對不對?我想讓他們在陣列中,但最後。無論如何,這對未來可能會很好。 – rdurand 2013-05-02 13:02:55

+0

@rdurand是代碼將刪除1行中低於0的所有值。之後它會根據您想要的順序進行排序。 – 2013-05-02 13:09:13

1

@ JeremyP的答案提供了適當的整理,也可能是你所追求的。

然而,對於完整性的方式與過濾器和標準compare:方法來做到這一點:

NSArray *numbers = @[@12, @0, @10, @15, @0, @3]; 

NSArray *sortedPositiveNumbers = [[numbers filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self > 0"]] sortedArrayUsingSelector:@selector(compare:)]; 
NSArray *zeroes = [numbers filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self = 0"]]; 

NSArray *result = [sortedPositiveNumbers arrayByAddingObjectsFromArray:zeroes]; 

感謝迦勒的火花。

+0

感謝您的回答! – rdurand 2013-05-02 14:40:32