3

我有两个 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

这两组中具有相同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)

做这个的最好方式是什么?

4

2 回答 2

8

@AliSoftware 的回答是一种有趣的方法。NSPredicate在 Core Data 之外非常慢,但这通常很好。如果性能有问题,您可以使用循环实现相同的算法,即多几行代码,但通常更快。

另一种方法是询问是否应始终将具有相同 ID 的两个人视为等效的。如果这是真的,那么你可以像这样覆盖你isEqual:hashperson 类(假设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具有广泛的影响,因此您需要确保在遇到具有相同标识符的两个人对象的每个地方,它们都应该被视为平等。但如果是这种情况,这确实会大大简化和加速您的代码。

于 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 回答