2011-09-30 2 views
3

私は2つのnssetsを持っています。オブジェクトの属性に基づいて2つのNSSetsを比較するにはどうすればよいですか?

nsset1: person.id = 1, person.id = 2, person.id = 3 
nsset2: person.id = 1, person.id = 2 

結果は次のようになります。

nsset1 - nsset2: person (with id 3) 
nsset2 - nsset1: null 

それらの二組で同じIDを持つこれらのオブジェクトは異なるオブジェクトであるので、私は単にminusSetを行うことができませんでした。このようにする必要があり

nsset1: person.id = 1, person.id = 2, person.id = 3 
nsset2: person.id = 4, person.id = 5 

結果::

は、私のような何かをしたい

nsset1 - nsset2: person (id 1), person (id 2), person (id 3) 
nsset2 - nsset1: person (id 4), person (id 5) 

これを行うための最善の方法は何ですか? AliSoftwareの答えは興味深いアプローチがある@

答えて

5

あなたはこの

NSSet* nsset1 = [NSSet setWithObjects:person_with_id_1, person_with_id_2, person_with_id_3, nil]; 
NSSet* nsset2 = [NSSet setWithObjects:person_with_id_2, person_with_id_4, nil]; 

// retrieve the IDs of the objects in nsset2 
NSSet* nsset2_ids = [nsset2 valueForKey:@"objectID"]; 
// only keep the objects of nsset1 whose 'id' are not in nsset2_ids 
NSSet* nsset1_minus_nsset2 = [nsset1 filteredSetUsingPredicate: 
    [NSPredicate predicateWithFormat:@"NOT objectID IN %@",nsset2_ids]]; 
+0

これはgootですが、 'reason: 'のようなエラーが出ます。フォーマット文字列を解析できません。" objectID NOT IN%@ "'これはオブジェクトの属性の本当の名前なので、 'objectID'を使用しました。前にフィルタリングする前にすべてが素敵に見える、私はIDなどを取得します。何か案が? – choise

+0

申し訳ありませんが私の答えを前にテストしていませんでした。 [述語プログラミングガイド](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html)では、NOT演算子は式全体に適用されます'IN'演算子のような別の演算子ではありません)、' objectID NOT IN%@ 'ではなく' NOT objectID IN%@ 'と書くべきです。それに応じて私の答えを更新しました。 – AliSoftware

+0

はい、 'NOT(objectID IN%@)'と思っています – choise

8

のようなものを試してみてください。 NSPredicateはCore Data以外ではかなり遅いですが、しばしば問題ありません。パフォーマンスに問題がある場合は、ループを使用して同じアルゴリズムを実装できます。これはコードの行数が増えますが、一般的には高速です。

もう1つの方法は、同じIDを持つ2人の人が常に同等と見なされるべきかどうかを尋ねることです。それが本当なら、あなたはこのようなあなたの人のクラスのisEqual:hashを上書きすることができます(identifierがNSUIntegerであると仮定した場合):

- (BOOL)isEqual:(id)other { 
    if ([other isMemberOfClass:[self class]) { 
    return ([other identifier] == [self identifier]); 
    } 
    return NO; 
} 

- (NSUInteger)hash { 
    return [self identifier]; 
} 

これをやって、すべてのNSSet操作はあなたので、等しいと同じ識別子を持つオブジェクトを扱いますminusSetを使用できます。また、NSMutableSet addObject:はあなたの識別子で自動的にユニークです。

isEqual:hashの実装には広範囲な影響があります。したがって、同じ識別子を持つ2つの人物が出現するすべての場所で同じものとして扱う必要があります。しかし、そういう場合は、コードを大幅に単純化してスピードアップします。

関連する問題