2012-10-30 75 views
2

我有一個NSArray包含幾個NSDictionary實例。除其他字段外,每個NSDictionary都有一個名爲rating的對象和一個numberOfVotes(均爲int)。如何對數組進行排序,以便按rating/numberOfVotes排序?更一般地說,我可以通過執行上述操作來對其進行分類嗎?或者,將每個操作的值添加到每個NSDictionary的另一個對象然後按此排序?NSArray按功能排序

謝謝

編輯 - 我已添加以下內容。仍然沒有正確排序。一個問題:這個數組是否應該適用於2個以上的對象。 (對象數量會有所不同)

[sortedArray sortedArrayUsingComparator:^NSComparisonResult(id dict1, id dict2) 
{ 
    MyObj *obj1 = (MyObj *)dict1; 
    MyObj *obj2 = (MyObj *)dict2; 

    int rating1 = obj1.rating.intValue; 
    int rating2 = obj2.rating.intValue; 

    int number1 = obj1.number_of_votes.intValue; 
    int number2 = obj2.number_of_votes.intValue; 

    double key1 = ((double)rating1)/number1; 
    double key2 = ((double)rating2)/number2; 

    if (key1 < key2) 
    { 
     return NSOrderedDescending; 
    } 

    if (key2 < key1) 
    { 
     return NSOrderedAscending; 
    } 
    return NSOrderedSame; 

}]; 

回答

4

您可以定義一個自定義比較器來使用您正在尋找的那種複合排序鍵。如果在字典中沒有充分的理由擁有該排序鍵,除了執行排序之外,不要將詞項添加到字典中。

array = [array sortedArrayUsingComparator: ^(id obj1, id obj2) { 
    int rating1 = [[obj1 objectForKey:@"rating"] intValue]; 
    int numberOfVotes1 = [[obj1 objectForKey:@"numberOfVotes"] intValue]; 
    int rating2 = [[obj2 objectForKey:@"rating"] intValue]; 
    int numberOfVotes2 = [[obj2 objectForKey:@"numberOfVotes"] intValue]; 
    double key1 = ((double)rating1)/numberOfVotes1; 
    double key2 = ((double)rating2)/numberOfVotes2; 
    if (key1 > key2) { 
     return (NSComparisonResult)NSOrderedDescending; 
    } 

    if (key1 < key2) { 
     return (NSComparisonResult)NSOrderedAscending; 
    } 
    return (NSComparisonResult)NSOrderedSame; 
}]; 

注:sortedArrayUsingComparator:方法不代替數組進行排序;相反,它返回一個排序的副本。如果您想要就地分揀,請使用NSMutableArray

+0

請參閱我的更新回答 –

+0

@AndreiFilip是的,這將適用於必要的項目。但是,這不會*排列陣列;它會返回數組的一個有序副本。 – dasblinkenlight

+0

它令人敬畏的cos它使用塊,ftw! ;-) –

0

您尋求的方法家族的前綴爲sortedArray

對於函數(這是多個選項之一),請參閱:-[NSArray sortedArrayUsingFunction:context:]

0

編輯:如果你想要做ratingnumberOfVotes分,你將有一個功能或比較塊進行排序或更換字典,其中有計算rating/numberOfVotes的方法的模型對象。使用NSSortDescriptor

NSArray *sorted = [array sortedArrayUsingDescriptors:[NSArray arrayWithObjects: 
    [NSSortDescriptor sortDescriptorWithKey:@"rating" ascending:YES], 
    [NSSortDescriptor sortDescriptorWithKey:@"numberOfVotes" ascending:YES], 
    nil] 
]; 
+0

它看起來像OP希望通過'numberOfVotes'劃分'rating',而不是通過'numberOfVotes'來解決衝突。 – dasblinkenlight

+0

啊。然後,OP將不得不使用比較器/函數(請參閱@dasblinkenlight)或從字典中轉到模型對象,並定義計算適當值以排序的方法。 – Jesper

1

的適當的方式將使用塊這樣

NSArray *sortedArray; 

sortedArray = [unsortedArray sortedArrayUsingComparator:^NSComparisonResult(id a, id b) { 
    float first = [[(NSDictionary*)a objectForKey:@"rating"] floatValue]/ 
         [[(NSDictionary*)a objectForKey:@"numberOfVotes"] floatValue]; 
    float second = [[(NSDictionary*)a objectForKey:@"rating"] floatValue]/ 
         [[(NSDictionary*)a objectForKey:@"numberOfVotes"] floatValue]; 
return [[NSNumber numberWithFloat:first] compare: [NSNumber numberWithFloat:second]]; 
}]; 

您可能會發現更多的方法來比較:

How to sort an NSMutableArray with custom objects in it?

0

過濾數據是在計算基本任務之一。

您可以通過多種方式進行排序。

  1. NSPredicate

    你可以看到的例子here

  2. NSSortDescriptor

    你可以看到的例子here

  3. 正則表達式

  4. Set操作

  5. 鍵 - 值編碼

0

理想情況下,你應該通過自定義對象替換NSDictionary,與像ratingnumberOfVotes性能。然後,您可以在此自定義對象上聲明方法compare:,並將其用作選擇器對數組進行排序。

您可以使用塊代碼對對象進行排序,但將實現抽象爲自定義對象會更清晰。

0

你可以在這裏使用NSSortDescriptor進行排序,例如你的數組包含幾個NSDictionnaries,名字是dataArray。

NSSortDescriptor * descriptor = [[NSSortDescriptor alloc] initWithKey:rating 
          ascending:YES]; 
NSArray * keyArrray = [NSArray arrayWithObjects:descriptor, nil]; 
NSArray * sortedArray = [dataArray sortedArrayUsingDescriptors:keyArrray]; 

在NSSortDescriptor的幫助下,我們可以對任何數據類型鍵值對進行排序。