Есть несколько способов сделать это, один из которых - использовать вспомогательный экземпляр 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];
}
}