2012-12-14 61 views
1

我有以下问题:我有一个整数数组,我想把它们放在一个数据结构中,每个整数都有其出现的数字,然后按数字排序的事件。用计数索引对数组进行排序

所以,如果我有:

[1, 3, 4, 6, 6, 3, 1, 3] 

我将有:

[(4,1), (6,2), (1,2), (3,3)] 

其中(X,Y)==(整数,它出现的次数)。

我试图使用NSCountedSet,但它不工作,我想知道什么是最好的方式来做到这一点。

到目前为止,我已经做了以下内容:

NSCountedSet *totalSet = [[NSCountedSet alloc] initWithArray:finalArray]; 

哪里finalArray是没有排序的全部原始数据的最后阵列。 totalSet被分组为(x,y)但未排序(理想情况下,应按'y'排序)。

我也试图做到这一点,但没有奏效:

NSArray *sortedArray = [finalArray sortedArrayUsingSelector:@selector(compare:)]; 

然后执行:

NSCountedSet *totalSet = [[NSCountedSet alloc] initWithArray:finalArray]; 

但是,这并没有改变 'totalSet'。

+0

你想要什么结果的结构是什么?字典数组是否正确? – rdelmar

+0

结果应该是按'y'排序的一系列(x,y)。 – moshikafya

回答

3

你可以把这些数字和他们的计数,以字典的数组像这样:

NSArray *arr = @[@1, @3, @4, @6, @6, @3, @1, @3]; 
    NSCountedSet *totalSet = [NSCountedSet setWithArray:arr]; 
    NSMutableArray *dictArray = [NSMutableArray array]; 
    for (NSNumber *num in totalSet) { 
     NSDictionary *dict = @{@"number":num, @"count":@([totalSet countForObject:num])}; 
     [dictArray addObject:dict]; 
    } 
    NSArray *final = [dictArray sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"number" ascending:YES ]]]; 
    NSLog(@"%@",final); 
+0

花了3个小时试图弄清楚这一点,谢谢你的回答! –

4

首先,让我们定义一个方便的元组类型,我们可以使用一些与它出现的次数关联:

@interface Pair : NSObject 
@property(nonatomic, strong) id key; 
@property(nonatomic, strong) id value; 
- (id)initWithKey:(id)key value:(id)value; 
@end 

@implementation Pair 
- (id)initWithKey:(id)key value:(id)value; 
{ 
    if((self = [super init])) { 
     _key = key; 
     _value = value; 
    } 
    return self; 
} 
- (NSString *)description 
{ 
    return [NSString stringWithFormat:@"(%@,%@)", self.key, self.value]; 
} 
@end 

然后,为了得到理想的效果,请使用计数集来算的出现,则将结果填入一个元组数组中,并按出现次数排序。

- (void)testOccurrenceCounting 
{ 
    NSArray *numbers = @[@1, @3, @4, @6, @6, @3, @1, @3]; 
    NSCountedSet *set = [[NSCountedSet alloc] initWithArray:numbers]; 
    NSMutableArray *counters = [NSMutableArray arrayWithCapacity:[set count]]; 
    [set enumerateObjectsUsingBlock:^(id obj, BOOL *stop) { 
     [counters addObject:[[Pair alloc] initWithKey:obj value:@([set countForObject:obj])]]; 
    }]; 
    [counters sortUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"value" ascending:YES]]]; 

    NSLog(@"%@", counters); 
} 

counters现在是Pair对象,这些对象的key属性保存数量的排序后的数组,并且value属性保存出现的次数,既作为盒装NSNumbers。从那里,你可以解开它们,或者按你认为合适的方式操纵收藏。

为了证明这个工程,这里的NSLog语句的输出:

(
    "(4,1)", 
    "(6,2)", 
    "(1,2)", 
    "(3,3)" 
) 
+0

好的答案....! – TheTiger

+0

美女。很好的答案。 – nithinbhaktha

2

这里是我的版本的答案。如果您不想使用自定义类,并且希望将它们作为单独数组按照其出现次数排序,则可以尝试此操作。

创建这样的功能,

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

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

,并使用此,

NSArray *finalArray = @[@1, @3, @4, @6, @6, @3, @1, @3];  
    NSCountedSet *totalSet = [[NSCountedSet alloc] initWithArray:finalArray]; 
    NSArray *sortedBasedOnCountArray = [[totalSet allObjects] sortedArrayUsingFunction:countedSort context:(__bridge void *)(totalSet)]; 
    NSLog(@"sortedObjectsBasedOnCountArray = %@", sortedBasedOnCountArray); 

    NSMutableArray *countArray = [NSMutableArray arrayWithCapacity:[sortedBasedOnCountArray count]]; 

    for (id object in sortedBasedOnCountArray) { 
     [countArray addObject:[NSNumber numberWithInt:[totalSet countForObject:object]]]; 
    } 
    NSLog(@"countArray = %@", countArray); 

输出:

sortedObjectsBasedOnCountArray = (
    4, 
    6, 
    1, 
    3 
) 

countArray = (
    1, 
    2, 
    2, 
    3 
) 

注意这两个数组以相同的顺序排序,数组的索引可以用来链接它们两个。

另请检查此NSBag实施。