问题
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