NSArray *arrClient = [[NSArray alloc] initWithObjects:@"record 1", @"record 2", nil];
NSArray *arrServer = [[NSArray alloc] initWithObjects:@"record 1", @"record 3", nil];
On arrServer I would like to apply predicates to filter only those entries that DON'T already exist in arrClient. e.g. in this case record 1 exist in both arrays and shall be ignored, hence only an array with one entry with the "record 3" string shall be returned.
Is this possible?
UPDATE
The answers below are great. I believe I need to give a real example to verify if what I am doing makes sense after all. (I am still giving a compact version below)
Now the clientItems will be of type FTRecord (Core Data)
@interface FTRecord : NSManagedObject
...
@property (nonatomic) NSTimeInterval recordDate;
@end
@implementation FTRecord
...
@dynamic recordDate;
@end
This class below is a holder for parsing json from a REST service. Hence the serverItems we mentioned earlier will be of this type.
@interface FTjsonRecord : NSObject <JSONSerializable>
{
}
@property (nonatomic) NSDate *recordDate;
@implementation FTjsonRecord
- (NSUInteger)hash
{
return [[self recordDate] hash];
}
- (BOOL)isEqual:(id)object
{
if ([object isKindOfClass:[FTjsonRecord self]]) {
FTjsonRecord *other = object;
return [[self recordDate] isEqualToDate:[other recordDate]];
}
else if ([object isKindOfClass:[FTRecord self]]) {
FTRecord *other = object;
return [[self recordDate] isEqualToDate:[NSDate dateWithTimeIntervalSinceReferenceDate:[other recordDate]]];
}
else {
return NO;
}
}
Going with Wain's example, this seems to work fine. Now is this feasible? Keep in mind that serverItems are just temporary and only used for syncing with server, and will be thrown away. clientItems is the one that remains in place.
UPDATE 2:
This time I am trying Manu's solution:
I have created this method on my Client DBStore, which is called by the predicate.
The reason I can't use containsObject is because the class types in serverItems and clientItems are not the same type.
-(BOOL)recordExistsForDate:(NSDate *)date
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"recordDate == %@", date];
NSArray *arr = [allRecords filteredArrayUsingPredicate:predicate];
if (arr && [arr count] > 0) {
return YES;
} else {
return NO;
}
}
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(FTjsonRecord *evaluatedObject, NSDictionary *bindings) {
return ![store recordExistsForDate:[evaluatedObject recordDate]];
}];
NSSet *set = [[serverRecords items] filteredSetUsingPredicate:predicate];
What worries me about this solution though, is the linear read from my clientItems (allRecords). I am not sure how efficient it is using the predicate on the array, wonder if there is a better way to achieve this.
NSSetinstead of predicates?