Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSCountedSet order by count

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)

like image 346
Choppin Broccoli Avatar asked Oct 27 '13 00:10

Choppin Broccoli


4 Answers

    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.

like image 75
Peter Foti Avatar answered Nov 15 '22 14:11

Peter Foti


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))")
}
like image 21
Lepidopteron Avatar answered Nov 15 '22 13:11

Lepidopteron


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

like image 34
0xWood Avatar answered Nov 15 '22 14:11

0xWood


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
like image 25
aLevelOfIndirection Avatar answered Nov 15 '22 12:11

aLevelOfIndirection