NSCountedSet order by count

4.2k views Asked by At

Does anyone know how to take an NSCountedSet of objects and create an array of those objects in order by their object count? (highest count to lowest)

4

There are 4 answers

0
Peter Foti On BEST ANSWER
    NSCountedSet *countedSet = [[NSCountedSet alloc] initWithArray:array2];

    NSMutableArray *dictArray = [NSMutableArray array];
    [countedSet enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
        [dictArray addObject:@{@"object": obj,
                               @"count": @([countedSet countForObject:obj])}];
    }];

    NSLog(@"Objects sorted by count: %@", [dictArray sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"count" ascending:NO]]]);

In the code above, array2 is an array of of 100 random strings, each with two letters. sortedArrayUsingDescriptors:, returns a sorted array, in this case it is sorted in descending order by the count of the objects.

2
aLevelOfIndirection On

Here is another way to achieve the same result:

NSArray *sortedValues = [countedSet.allObjects sortedArrayUsingComparator:^(id obj1, id obj2) {
    NSUInteger n = [countedSet countForObject:obj1];
    NSUInteger m = [countedSet countForObject:obj2];
    return (n <= m)? (n < m)? NSOrderedAscending : NSOrderedSame : NSOrderedDescending;
}];

To get the values in descending order you could use (or reverse the above return value).

sortedValues.reverseObjectEnumerator.allObjects
0
0xWood On

Here is a Swift version:

let sorted = countedSet.allObjects.sort { return countedSet.countForObject($0.0) < countedSet.countForObject($0.1) }

Just change the < to > for descending order

2
Lepidopteron On

For Swift3 you need to modify the provided swift code a bit:

let countedSet = [1,2,2,4,6,7,8,8,5,8,1]

let sorted = countedSet.allObjects.sorted { return countedSet.count(for: $0.0) > countedSet.count(for: $0.1) }

// iterate over all items in the set
for item in countedSet {
    print("\(item): Count - \(countedSet.count(for: item))")
}