NSMutableArray计算对象的出现次数,然后重新排列数组
我一直在寻找修改可以容纳同一对象的多个实例的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];
您可以使用isKindOfClass & isMemberOfClass实例方法进行管理。因此,只需循环访问阵列,并根据您的要求继续将项目推入新阵列
有几种方法可以做到这一点,其中一种方法是使用辅助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];
}
}
这听起来像个好主意,但并不完全。它会混淆对象,因为那里有多个对象具有相同数量的多个对象。 OP需要确定他们想要如何排序具有相同计数的对象组,并将其合并到排序方法中。 – extremeboredom 2011-06-08 10:45:48
@extr啊,真的!我会发布对这个问题的评论。 – 2011-06-08 10:51:03
你需要的是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
当你有对象的两个“组”具有相同的大小,你期待什么行为?说object2,object3,object4是同一个对象,而object1,object7,object8是同一个对象。由于这两个对象出现次数最多,它们的相应数组元素是否需要在结果数组中连续? – 2011-06-08 10:53:27