Вопрос

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

Это было полезно?

Решение

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

[[mySet allObjects] sortedArrayUsingDescriptors:descriptors];

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

[mySet sortedArrayUsingDescriptors:descriptors];

Другие советы

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

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

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

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

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

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

Одним из возможных недостатков является то, что эти классы (на данный момент) не являются подклассами NS(Mutable)Set, поэтому, если вам необходимо передать 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...И все верхние подсказки работают только с Array :)

NSArray *myArray = [mySet sortedArrayUsingDescriptors:descriptors];

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top