简体   繁体   English

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

[英]How to compare two NSSets based on attributes of objects?

I have two nssets. 我有两个nssets。

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

Results should be: 结果应该是:

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

These objects with the same id in those two sets are different objects, so I couldn't simply do minusSet. 这两个集中具有相同id的对象是不同的对象,所以我不能简单地做minusSet。

I want to do something like: 我想做的事情如下:

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

Results should be like this: 结果应该是这样的:

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

What is the best way to do this? 做这个的最好方式是什么?

@AliSoftware's answer is an interesting approach. @AliSoftware的答案是一个有趣的方法。 NSPredicate is pretty slow outside of Core Data, but that often is fine. NSPredicate在Core Data之外相当缓慢,但通常都很好。 If the performance is a problem, you can implement the same algorithm with a loop, which is a few more lines of code, but generally faster. 如果性能有问题,您可以使用循环实现相同的算法,这是一些代码行,但通常更快。

Another approach is to ask whether two persons with the same ID should always be considered equivalent. 另一种方法是询问具有相同身份证的两个人是否应始终被视为等同。 If that's true, then you can override isEqual: and hash for your person class like this (assuming identifier is an NSUInteger): 如果这是真的,那么你可以覆盖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];
}

Doing this, all NSSet operations will treat objects with the same identifier as equal, so you can use minusSet . 这样做,所有NSSet操作都会将具有相同标识符的对象视为相等,因此您可以使用minusSet Also NSMutableSet addObject: will automatically unique for you on identifier. 另外NSMutableSet addObject:将自动为您标识符唯一。

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. 实现isEqual:并且hash具有广泛的影响,因此您需要确保遇到具有相同标识符的两个人对象的每个位置,它们应被视为相等。 But if that's you case, this does greatly simplify and speed up your code. 但如果是这种情况,这会大大简化并加快代码速度。

You should try something like this 你应该尝试这样的事情

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM