0
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”字符串的条目的数组。

这可能吗?

更新

下面的答案很棒。我相信我需要举一个真实的例子来验证我所做的事情是否有意义。(我仍然在下面给出一个紧凑的版本)

现在,clientItems 的类型将是 FTRecord(核心数据)

@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;
    }
}

以 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) 的线性读取。我不确定在数组上使用谓词的效率如何,想知道是否有更好的方法来实现这一点。

4

2 回答 2

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];
于 2013-10-28T16:41:24.317 回答
0

取决于您要使用的谓词:

你可以使用这个参数数组

[NSPredicate predicateWithFormat:<#(NSString *)#> argumentArray:<#(NSArray *)#>];

并使用数组中的对象构建您的谓词

或使用带有块的谓词

[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
    <#code#>
}]

并在块中评估对象,将其与数组中的对象进行比较

您可以做的一个可能的检查是:

return ![arrClient containsObject:evaluatedObject];

将排除 arrClient 中包含的对象

containsObject: 使用 'isEqual:' 比较对象

于 2013-10-28T15:59:01.423 回答