web-dev-qa-db-ja.com

NSSetをソートする最も効率的な方法は何ですか?

セット内のオブジェクトのプロパティに基づいてNSSet/NSMutableSet内のオブジェクトをソートする最も効率的な方法は何ですか?今のところ、各オブジェクトを繰り返し処理し、NSMutableArrayに追加し、その配列をNSSortDescriptorで並べ替えています。

63
Boon

使ってみて

[[mySet allObjects] sortedArrayUsingDescriptors:descriptors];

編集:iOS≥4.0およびMac OS X≥10.6では、直接使用できます

[mySet sortedArrayUsingDescriptors:descriptors];
114
cobbal

オブジェクトのセットをソートする「最も効率的な方法」は、実際の意味によって異なります。偶然の仮定(前の回答で作成されたもの)は、セット内のオブジェクトの1回限りの並べ替えです。この場合、@ cobbalが提案するものと、あなたが思いついたものとの間のトスアップだと思います。おそらく次のようなものです。

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

(@cobbalのアプローチでは2つの自動解放された配列が作成されるため、トスアップだと言います。これにより、メモリフットプリントが2倍になります。

ただし、、セット内の要素を複数回ソートしている場合(特に通常の場合)、これは間違いなく効率的なアプローチではありません。 NSMutableArrayを保持し、NSSetとの同期を維持し、毎回-sortUsingDescriptors:を呼び出しますが、配列が既にソートされている場合でも、N個の比較が必要です。

Cocoa自体は、コレクションをソート順に維持するための効率的なアプローチを提供しません。 Javaには TreeSet クラスがあり、オブジェクトが挿入または削除されるたびに要素をソートされた順序で維持しますが、Cocoaはそうではありません。私自身の使用のために同様のものを開発します。

私が継承して改良したデータ構造フレームワークの一部として、 プロトコルとソートされたセットのいくつかの実装 を作成しました。具象サブクラスはいずれも、ソートされた順序で一連の個別のオブジェクトを保持します。まだ改善すべき点があります。最も重要なのは、-compare:(セット内の各オブジェクトが実装する必要がある)の結果に基づいてソートし、NSSortDescriptorをまだ受け入れないことです。 (回避策は、-compare:を実装して、オブジェクトの目的のプロパティを比較することです。)

考えられる欠点の1つは、これらのクラスが(現在)NS(Mutable)Setのサブクラスではないため、NSSetを渡す必要がある場合、順序付けされないことです。 (プロトコルにはNSSetを返す-setメソッドがあり、もちろん順序付けられていません。)フレームワークのNSMutableDictionaryサブクラスで行ったように、すぐに修正する予定です。フィードバックは大歓迎です。 :-)

15
Quinn Taylor

IOS≥5.0およびMac OS X≥10.7の場合、NSOrderedSetを直接使用できます

8
bioffe

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];
2
stefanB

OS X 10.7およびiOS 5.0以降、NSOrderedSetがあります。これを使用して、オブジェクトをセットに保ち、順序を維持できます。 NSMutableOrderedSetにはソートのメソッドがあります。ソートされたアイテムを保存するためにNSArrayのような個別のオブジェクトを作成する必要がないため、状況によってはパフォーマンスが向上する場合があります。

0
Andriy

「sortedArrayUsingFunction:」はNSArrayとして結果を設定するため、NSSetをソートできません...そして、すべての上位ヒントは配列のみで機能します:)

NSArray *myArray = [mySet sortedArrayUsingDescriptors:descriptors];

完璧に動作し、他の方法は必要ありません:)

0
iTux