NSArray *arrClient = [[NSArray alloc] initWithObjects:@"record 1", @"record 2", nil];
NSArray *arrServer = [[NSArray alloc] initWithObjects:@"record 1", @"record 3", nil];
在arrServer
上我想应用谓词来仅过滤那些arrClient
中尚未存在的条目。例如在这种情况下,record 1
存在于两个数组中并且应该被忽略,因此只返回一个带有“record 3”字符串的数组的数组。
这可能吗?
更新
以下答案很棒。我相信我需要给出一个真实的例子来验证我所做的事情是否有意义。 (我仍然在下面给出一个紧凑版本)
现在clientItems的类型为FTRecord(核心数据)
@interface FTRecord : NSManagedObject
...
@property (nonatomic) NSTimeInterval recordDate;
@end
@implementation FTRecord
...
@dynamic recordDate;
@end
下面这个类是从REST服务解析json的持有者。因此,我们之前提到的serverItem将属于这种类型。
@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;
}
}
按照Wain的例子,这似乎工作正常。现在这可行吗? 请记住,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)的线性读取。我不确定在阵列上使用谓词的效率如何,想知道是否有更好的方法来实现这一点。
答案 0 :(得分:1)
您可以使用NSSet
来获取其他集合的联合,交集和差异(减号)。这更准确地匹配您要做的事情。
NSMutableSet *serverItems = [[NSMutableSet alloc] init];
[arrServerItems addObjectsFromArray:arrServer];
NSSet *clientItems = [[NSSet alloc] init];
[clientItems addObjectsFromArray:arrClient];
[arrServerItems minus:clientItems];
这确实删除了订购信息。
对于谓词,您可以使用:
NSPredicate *filterPredicate = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)", arrClient];
答案 1 :(得分:0)
取决于您要使用的谓词:
您可以使用此
来使用一组参数[NSPredicate predicateWithFormat:<#(NSString *)#> argumentArray:<#(NSArray *)#>];
使用数组中的对象构建谓词
或使用带块的谓词
[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
<#code#>
}]
并在块中展开对象,将其与数组中的对象进行比较
您可以做的可能检查是:
return ![arrClient containsObject:evaluatedObject];
将排除arrClient中包含的对象
containsObject:使用'isEqual:'来比较对象