How to compare two NSSets based on attributes of objects?

杀马特。学长 韩版系。学妹 提交于 2020-01-23 09:55:26

问题


I have two 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.

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?


回答1:


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



回答2:


@AliSoftware's answer is an interesting approach. NSPredicate is pretty slow outside of Core Data, but that often is fine. 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):

- (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.



来源:https://stackoverflow.com/questions/7613895/how-to-compare-two-nssets-based-on-attributes-of-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!