NSArray *arrClient = [[NSArray alloc] initWithObjects:@"record 1", @"record 2", nil];
NSArray *arrServer = [[NSArray alloc] initWithObjects:@"record 1", @"record 3", nil];
にまだ存在しないエントリのみをフィルタリングする述語arrServer
を適用したいと思いますarrClient
。たとえば、この場合record 1
、両方の配列に存在し、無視されるため、「レコード 3」文字列を持つ 1 つのエントリを持つ配列のみが返されます。
これは可能ですか?
アップデート
以下の答えは素晴らしいです。結局、私がやっていることは意味があるかどうかを確認するために、実際の例を示す必要があると思います. (私はまだ以下のコンパクトバージョンを提供しています)
clientItems のタイプは FTRecord (Core Data) になります。
@interface FTRecord : NSManagedObject
...
@property (nonatomic) NSTimeInterval recordDate;
@end
@implementation FTRecord
...
@dynamic recordDate;
@end
以下のこのクラスは、REST サービスから json を解析するためのホルダーです。したがって、前述の serverItems はこのタイプになります。
@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;
}
}
ウェインの例では、これはうまくいくようです。今、これは実現可能ですか?serverItems は一時的なものであり、サーバーとの同期にのみ使用され、破棄されることに注意してください。clientItems はそのまま残ります。
更新 2:
今回はManuのソリューションを試しています:
クライアント DBStore でこのメソッドを作成しました。このメソッドは、述語によって呼び出されます。使用できない理由containsObject
は、serverItems と clientItems のクラス タイプが同じタイプではないためです。
-(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];
ただし、このソリューションについて心配しているのは、clientItems (allRecords) からの線形読み取りです。配列で述語を使用することがどれほど効率的かはわかりません。これを達成するためのより良い方法があるかどうか疑問に思います。