There are several ways to do this, one of which is by using a helper instance NSCountedSetand a function that uses to do this 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;
}
and
NSMutableArray *array = …;
NSCountedSet *countedSet = [[[NSCountedSet alloc] initWithArray:array]
autorelease];
[array sortUsingFunction:countedSort context:countedSet];
Edit: extremeboredom skillfully remarked that if two different objects have the same repeat counter, then the corresponding elements will not necessarily be adjacent in the resulting array. This solution should only be used if it is not required that the same objects be adjacent.
:, , , , , . , . - , distinctArray, .
NSMutableArray *array = …;
NSCountedSet *countedSet = [[[NSCountedSet alloc] initWithArray:array]
autorelease];
NSArray *distinctArray = [[countedSet allObjects]
sortedArrayUsingFunction:countedSort context:countedSet];
NSMutableArray *sortedArray = [NSMutableArray arrayWithCapacity:[array count]];
for (id object in distinctArray) {
for (NSUInteger i = 0; i < [countedSet countForObject:object]; i++) {
[sortedArray addObject:object];
}
}
user557219