2011-06-08 53 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