如何根据对象的属性比较两个NSSets?

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

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

你应该尝试这样的事情

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

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

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