68

セット内のオブジェクトのプロパティに基づいてNSSet/内のオブジェクトを並べ替える最も効率的な方法は何ですか?NSMutableSet現在、私が行っている方法は、各オブジェクトを反復処理し、それらをに追加して、NSMutableArrayその配列を。で並べ替えることNSSortDescriptorです。

4

6 に答える 6

117

使ってみてください

[[mySet allObjects] sortedArrayUsingDescriptors:descriptors];

編集:iOS≥4.0およびMac OSX≥10.6の場合、直接使用できます

[mySet sortedArrayUsingDescriptors:descriptors];
于 2009-07-01T01:12:21.527 に答える
15

オブジェクトのセットをソートする「最も効率的な方法」は、実際の意味によって異なります。カジュアルな仮定(前の回答が行う)は、セット内の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サブクラスで行ったように、すぐに修正する予定です。フィードバックは大歓迎です。:-)

于 2009-07-01T04:20:53.373 に答える
8

iOS≥5.0およびMacOSX≥10.7の場合、直接使用できますNSOrderedSet

于 2012-01-12T18:39:15.043 に答える
2

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];
于 2009-07-01T01:09:13.483 に答える
0

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

NSArray *myArray = [mySet sortedArrayUsingDescriptors:descriptors];

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

于 2011-04-25T04:30:51.553 に答える
0

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

于 2016-06-01T05:45:36.600 に答える