Каков наиболее эффективный способ сортировки NSSet?


каков наиболее эффективный способ сортировки объектов в NSSet/NSMutableSet на основе свойства объектов в наборе? Прямо сейчас, как я это делаю, повторяя каждый объект, добавьте их в NSMutableArray, и сортировать этот массив с NSSortDescriptor.

6 63

6 ответов:

попробуйте использовать

[[mySet allObjects] sortedArrayUsingDescriptors:descriptors];

Edit: для iOS ≥ 4.0 и Mac OS X ≥ 10.6 вы можете напрямую использовать

[mySet sortedArrayUsingDescriptors:descriptors];

"наиболее эффективный способ" сортировки набора объектов зависит от того, что вы на самом деле имеете в виду. Случайное предположение (которое делают предыдущие ответы)-это одноразовый вид объектов в наборе. В этом случае, я бы сказал, что это в значительной степени жеребьевка между тем, что @cobbal предполагает и то, что вы придумали - наверное, что-то вроде следующего:

NSMutableArray* array = [NSMutableArray arrayWithCapacity:[set count]];
for (id anObject in set)
    [array addObject:anObject];
[array sortUsingDescriptors:descriptors];

(Я говорю, что это жеребьевка, потому что подход @cobbal создает два автореализованных массива, поэтому объем памяти удваивает. Это несущественно для небольших наборов объектов, но и технически, ни один из подходов не является очень эффективным.)

, если вы сортируете элементы в наборе более одного раза (и особенно если это обычная вещь), это определенно не эффективный подход. Вы можете сохранить NSMutableArray вокруг и синхронизировать его с NSSet, а затем вызывать-sortUsingDescriptors: каждый раз, но даже если массив уже отсортирован, он все равно потребует N сравнения.

какао само по себе просто не обеспечивает эффективный подход для поддержания коллекции в отсортированном порядке. В Java TreeSet класс, который поддерживает элементы в отсортированном порядке всякий раз, когда объект вставляется или удаляется, но какао не делает. Именно эта проблема заставила меня разработать нечто подобное для собственного использования.

в рамках структуры данных, которую я унаследовал и обновил, я создал протокол и несколько реализации для отсортированных наборов. Любой из конкретных подклассов будет поддерживать набор различных объектов в отсортированном порядке. Есть еще уточнения, которые нужно сделать - прежде всего, что он сортирует на основе результата-compare: (который каждый объект в наборе должен реализовать) и еще не принимает NSSortDescriptor. (Обходной путь заключается в реализации-compare: для сравнения интересующего свойства на объектах.)

одним из возможных недостатком является то, что эти классы (в настоящее время) не подклассы набора NS(Mutable), поэтому, если вы должны передать NSSet, он не будет заказан. (Протокол имеет метод-set, который возвращает NSSet, который, конечно же, неупорядочен.) Я планирую исправить это в ближайшее время, как я сделал с подклассами NSMutableDictionary в рамках. Обратная связь, безусловно, приветствуется. : -)

для iOS ≥ 5.0 и Mac OS X ≥ 10.7 вы можете напрямую использовать NSOrderedSet

NSSet-это набор неупорядоченных объектов. Глядя на массивы ссылок apple, упорядочиваются коллекции.

глядя на 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];

вы не можете сортировать NSSet, потому что "sortedArrayUsingFunction:" установить результат как NSArray... И все верхние подсказки работают только с массивом:)

NSArray *myArray = [mySet sortedArrayUsingDescriptors:descriptors];

работать идеально, и не нужно другим путем :)

начиная с OS X 10.7 и iOS 5.0 есть NSOrderedSet. Вы можете использовать его, чтобы держать объекты в наборе и поддерживать их порядок. NSMutableOrderedSet имеет методы сортировки. В некоторых ситуациях это может привести к повышению производительности, так как вам не нужно создавать отдельный объект, например NSArray для хранения отсортированных элементов.