3

私は 2 つの nsset を持っています。

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

これら 2 つのセットで同じ ID を持つオブジェクトは異なるオブジェクトであるため、単純にマイナスセットを行うことはできませんでした。

私は次のようなことをしたい:

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)

これを行う最善の方法は何ですか?

4

2 に答える 2

8

@AliSoftwareの答えは興味深いアプローチです。NSPredicateコアデータ以外ではかなり遅いですが、それでも問題ないことがよくあります。パフォーマンスに問題がある場合は、ループを使用して同じアルゴリズムを実装できます。これは、数行のコードですが、通常は高速です。

別のアプローチは、同じIDを持つ2人が常に同等であると見なされるべきかどうかを尋ねることです。それが本当なら、あなたはオーバーライドすることができisEqual:hashあなたの人のクラスのためにこのようになります(identifierNSUIntegerであると仮定します):

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

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

Doing this, all NSSet operations will treat objects with the same identifier as equal, so you can use minusSet. Also NSMutableSet addObject: will automatically unique for you on identifier.

Implementing isEqual: and hash has broad-reaching impacts, so you need to make sure that everyplace you encounter two person objects with the same identifier, they should be treated as equal. But if that's you case, this does greatly simplify and speed up your code.

于 2011-09-30T17:50:57.060 に答える
6

このようなことを試してみてください

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]];
于 2011-09-30T17:35:26.613 に答える