NSMutableArray 计算对象的出现次数,然后重新排列数组
Posted
技术标签:
【中文标题】NSMutableArray 计算对象的出现次数,然后重新排列数组【英文标题】:NSMutableArray counting occurrences of objects and then rearrange the array 【发布时间】:2011-06-08 09:42:20 【问题描述】:我一直在寻找修改可以容纳同一对象的多个实例的 NSMutableArray 的最佳方法。我也为 4.0 以下的 ios 版本工作,所以使用块不是要走的路。
情况如下:
我有一个这样的数组:
ARRAY = [object1,object2,object3,object4,object5,object6,object7,object8];
假设object2 object3 和object4 实际上是同一个对象。对象 1 和对象 7 也是如此。然后我想重新排列数组,以便最先出现,依此类推。所以数组必须看起来像这样:
[object2,object3,object4,object1,object7,object5,object6,object8];
【问题讨论】:
当您有两个“组”大小相同的对象时,您期望什么行为?说object2,object3,object4是同一个object,object1,object7,object8是同一个object。既然这两个对象出现次数最多,那么它们对应的数组元素在结果数组中是否需要连续? 【参考方案1】:有几种方法可以做到这一点,其中一种是使用辅助 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 巧妙地注意到,如果两个不同的对象具有相同的重复计数,那么它们对应的元素在结果数组中不一定是连续的。此解决方案仅应在相同对象不需要连续的情况下使用。
进一步编辑:如果您需要表示同一对象的元素是连续的,您可以创建一个仅包含不同元素的较小数组,并按其重复次数排序。然后,创建另一个数组,其中元素按重复计数排序。根据您的需要,您可能实际上并不需要结果数组 - 可能只需要 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 需要确定他们希望如何对具有相同计数的对象组进行排序,并将其合并到排序方法中。 @extr 啊,真的!我会就这个问题发表评论。【参考方案2】:您需要的是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] );
输出:
cc, 1
b, 1
B, 1
c, 2
a, 2
【讨论】:
【参考方案3】:您可以使用 isKindOfClass 和 isMemberOfClass 实例方法来管理它。因此,只需循环遍历您的数组并根据您的要求继续将项目推送到新数组中
【讨论】:
以上是关于NSMutableArray 计算对象的出现次数,然后重新排列数组的主要内容,如果未能解决你的问题,请参考以下文章
Power BI DAX 度量:考虑视觉对象的筛选上下文,计算列中值的出现次数