Каков наиболее эффективный способ сортировки объектов в NSSet
/NSMutableSet
на основе свойств объектов в наборе? Прямо сейчас, как я делаю это, итерации через каждый объект, добавьте их в NSMutableArray
и отсортируйте этот массив с помощью NSSortDescriptor
.Каков наиболее эффективный способ сортировки NSSet?
ответ
попробуйте использовать
[[mySet allObjects] sortedArrayUsingDescriptors:descriptors];
Edit: Для IOS ≥ 4.0 и Mac OS X ≥ 10.6 вы можете непосредственно использовать
[mySet sortedArrayUsingDescriptors:descriptors];
NSSet представляет собой набор неупорядоченных объектов. Глядя на ссылки на яблоки Массивы - это упорядоченные коллекции.
Глядя на NSArray есть обсуждение с примерами сортировки на http://developer.apple.com/documentation/Cocoa/Conceptual/Collections/Articles/sortingFilteringArrays ...
Пример по ссылке:
NSInteger alphabeticSort(id string1, id string2, void *reverse)
{
if (*(BOOL *)reverse == YES) {
return [string2 localizedCaseInsensitiveCompare:string1];
}
return [string1 localizedCaseInsensitiveCompare:string2];
}
// assuming anArray is array of unsorted strings
NSArray *sortedArray;
// sort using a selector
sortedArray =
[anArray sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
// sort using a function
BOOL reverseSort = NO;
sortedArray =
[anArray sortedArrayUsingFunction:alphabeticSort context:&reverseSort];
Вау, этот пример кода образца Apple довольно ужасен. Почему они используют void *, NSInteger и int, где проще использовать BOOL? Почему он должен возвращать NSInteger вместо NSComparisonResult? Я уверен, что он совместим с предыдущими решениями API, но это ужасно! Я предлагаю использовать селектор (метод), а не функцию сортировки коллекций Cocoa - это проще и элегантнее. –
@QuinnTaylor Я только что проверил и, конечно же, документацию для 'sortedArrayUsingFunction: context:' говорит, что ожидается, что функция примет два 'id' и 'void *' и вернет' NSInteger'. При этом, по крайней мере, образец правильный. (Кажется, они тоже его обновили - теперь это отстойно.) –
«Наиболее эффективным способом» для сортировки набора объектов варьируется в зависимости от того, что вы на самом деле означает. Случайное предположение (которое были сделаны предыдущими ответами) является одноразовым видом объектов в наборе. В этом случае, я бы сказал, что это в значительной степени жеребьевкой между тем, что @cobbal предполагает и то, что вы придумали - вероятно, что-то вроде следующего:
NSMutableArray* array = [NSMutableArray arrayWithCapacity:[set count]];
for (id anObject in set)
[array addObject:anObject];
[array sortUsingDescriptors:descriptors];
(я говорю это жеребьевкой потому что @ cobbal подход создает два autoreleased массивов, так что объем памяти удваивается. Это является несущественным для небольших наборов объектов, но технически, ни один подход не очень эффективен.)
Однако, если вы сортируете элементы набор более одного раза (и особенно, если это обычная вещь), это определенно не эффективный подход. Вы можете поддерживать NSMutableArray и синхронизировать его с NSSet, а затем вызывать -sortUsingDescriptors: каждый раз, но даже если массив уже отсортирован, он все равно потребует N сравнений.
Какао сам по себе просто не обеспечивает эффективного подхода к поддержанию коллекции в отсортированном порядке. Java имеет класс TreeSet, который поддерживает элементы в отсортированном порядке всякий раз, когда объект вставлен или удален, но Cocoa этого не делает. Именно эта проблема заставила меня разработать нечто подобное для моего собственного использования.
Как часть структуры структур данных, которую я унаследовал и обновил, я создал protocol and a few implementations for sorted sets. Любой из конкретных подклассов будет поддерживать набор различных объектов в отсортированном порядке. Есть еще уточнения, которые должны быть сделаны: главное, что он сортируется на основе результата -compare: (который должен реализовать каждый объект в наборе) и еще не принимает NSSortDescriptor. (Обходной путь заключается в реализации -compare: для сравнения интересующего объекта на объектах.)
Одним из возможных недостатков является то, что эти классы (в настоящее время) не являются подклассами NS (Mutable) Set, поэтому, если вы должны передать NSSet, он не будет заказан. (У протокола есть метод -set, который возвращает NSSet, который, конечно, неупорядочен.) Я планирую исправить это в ближайшее время, как это было сделано с подклассами NSMutableDictionary в рамках. Обратная связь, безусловно, приветствуется.:-)
Вы не можете сортировать NSSet, потому что «sortedArrayUsingFunction:» установить результат, как NSArray ... И все верхнее работу подсказки только с массивом :)
NSArray *myArray = [mySet sortedArrayUsingDescriptors:descriptors];
Работа совершена, и не нужен другой путь :)
для IOS ≥ 5.0 и Mac OS X ≥ 10.7 вы можете непосредственно использовать NSOrderedSet
Это не означает, t задайте вопрос, где у вас есть существующий NSSet и хотите его отсортировать. – colincameron
Поскольку OS X 10.7 и прошивкой 5.0 есть NSOrderedSet
. Вы можете использовать его для хранения объектов в наборе и сохранения их порядка. NSMutableOrderedSet
имеет методы сортировки. В некоторых ситуациях это может привести к улучшению производительности, поскольку вам не нужно создавать отдельный объект, например NSArray
, для хранения отсортированных элементов.
Короткие и сладкие! – Boon
Это не сильно отличается от предложения афера и, вероятно, примерно эквивалентно по скорости, поскольку -allObjects возвращает автореализованный NSArray и -sortedArrayUsingDescriptors: возвращает отдельный NSArray (оба неизменяемы). Стоимость выделения двух массивов не намного меньше, чем перечисление всех элементов в (умеренный размер) и требует в два раза больше места. –
Следует отметить, что sortedArrayUsingDescriptors: это только метод 10.6. Если вы настроили таргетинг на 10,5 или до того, как вы захотите попробовать @ подход QuinnTaylor – Austin