2011-06-08 49 views
5

我一直在尋找修改可以容納同一對象的多個實例的NSMutableArray的最佳方法。我也爲4.0版本以下的iOS版本工作,所以使用塊是不是要走的路。NSMutableArray計算對象的出現次數,然後重新排列數組

這裏的情況:

我有一個這樣的數組:

ARRAY = [object1,object2,object3,object4,object5,object6,object7,object8]; 

假設對象2 object3和object4實際上是相同的對象。還有object1和object 7。然後我想重新排列數組,以便最先出現的次數最多,等等。所以陣列將看起來像這樣:

[object2,object3,object4,object1,object7,object5,object6,object8];

+0

當你有對象的兩個「組」具有相同的大小,你期待什麼行爲?說object2,object3,object4是同一個對象,而object1,object7,object8是同一個對象。由於這兩個對象出現次數最多,它們的相應數組元素是否需要在結果數組中連續? – 2011-06-08 10:53:27

回答

0

您可以使用isKindOfClass & isMemberOfClass實例方法進行管理。因此,只需循環訪問陣列,並根據您的要求繼續將項目推入新陣列

6

有幾種方法可以做到這一點,其中一種方法是使用輔助NSCountedSet實例和使用NSCountedSet進行比較的函數:

NSInteger countedSort(id obj1, id obj2, void *context) { 
    NSCountedSet *countedSet = context; 
    NSUInteger obj1Count = [countedSet countForObject:obj1]; 
    NSUInteger obj2Count = [countedSet countForObject:obj2]; 

    if (obj1Count > obj2Count) return NSOrderedAscending; 
    else if (obj1Count < obj2Count) return NSOrderedDescending; 
    return NSOrderedSame; 
} 

NSMutableArray *array = …; 

NSCountedSet *countedSet = [[[NSCountedSet alloc] initWithArray:array] 
    autorelease]; 

[array sortUsingFunction:countedSort context:countedSet]; 

編輯: extremeboredom^h如巧妙地注意到,如果兩個不同的對象具有相同的重複計數,則它們的相應元素在結果數組中不一定是連續的。只有在相同對象不需要連續的情況下才需要使用此解決方案。


此外編輯:以便在需要表示同一對象的元件是連續的,則可以創建具有不同元件只,可以通過重複計數排序的更小的陣列。然後,創建另一個數組,其元素按重複次數排序。根據您的需要,您可能實際上不需要生成的陣列 - 可能只有distinctArray &計數的設置就足夠了。

NSMutableArray *array = …; 
NSCountedSet *countedSet = [[[NSCountedSet alloc] initWithArray:array] 
    autorelease]; 

// Array with distinct elements only, sorted by their repeat count 
NSArray *distinctArray = [[countedSet allObjects] 
    sortedArrayUsingFunction:countedSort context:countedSet]; 

// Array with all the elements, where elements representing the same 
// object are contiguous 
NSMutableArray *sortedArray = [NSMutableArray arrayWithCapacity:[array count]]; 
for (id object in distinctArray) { 
    for (NSUInteger i = 0; i < [countedSet countForObject:object]; i++) { 
     [sortedArray addObject:object]; 
    } 
} 
+0

這聽起來像個好主意,但並不完全。它會混淆對象,因爲那裏有多個對象具有相同數量的多個對象。 OP需要確定他們想要如何排序具有相同計數的對象組,並將其合併到排序方法中。 – extremeboredom 2011-06-08 10:45:48

+0

@extr啊,真的!我會發布對這個問題的評論。 – 2011-06-08 10:51:03

1

你需要的是NSBag, by Erica Sadun(GitHub)。簡單的例子:

NSArray *objArray = @[ @"a", @"a", @"b", @"B", @"c", @"cc", @"c"];  
NSBag  *aBag = NSBag.new; 

for (id thing in objArray)  [aBag add:thing]; // fill the bag 

for (id unique in aBag.objects)     // count'em out 
     NSLog( @"%@,  %i", 
        unique, [aBag occurrencesOf:unique]); 

OUTPUT:

cc, 1 
b, 1 
B, 1 
c, 2 
a, 2