如何使用 NSPredicate 从另一个 NSMutableArray 中过滤 NSMutableArray

Posted

技术标签:

【中文标题】如何使用 NSPredicate 从另一个 NSMutableArray 中过滤 NSMutableArray【英文标题】:How to filter NSMutableArray from another NSMutableArray using NSPredicate 【发布时间】:2013-10-20 18:28:09 【问题描述】:

我在数据库中有一些消息,每次我都会从该用户的服务器获取全部消息。 我必须比较两个数组并且需要过滤新消息。每条消息都有一个唯一的 id,即 messageId

NSMutableArray *arrayMessagesServer = [response objectForKey:@"messageList"];
    arrayMessagesDB=[[NSMutableArray alloc]initWithArray:[self getMessagesFromDB]];



    for (int i = 0; i<[arrayMessagesServer count]; i++)
    

        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"messageId == %i", [[arrayMessagesServer objectAtIndex:i] integerValue]];


        //If message not exists, saving message to DB
        if(![arrayMessagesDB filteredArrayUsingPredicate:predicate])
        
            NSDictionary *dict = [arrayForMessagesInServer objectAtIndex:i];

            Messages *objMessages = [NSEntityDescription insertNewObjectForEntityForName:@"Messages" inManagedObjectContext:context];
            [objMessages setValue:[dict objectForKey:@"message"] forKey:@"messageBody"];
            [objMessages setValue:[dict objectForKey:@"messageId"] forKey:@"messageId"];
            [objMessages setValue:[NSString stringWithFormat:@"%@",[dict objectForKey:@"messageType"]] forKey:@"messageType"];
        

    

    NSError *error1;
    if (![context save:&error1])
    
        NSLog(@"Problem saving: %@", [error1 localizedDescription]);
    

【问题讨论】:

太棒了!向我们展示一些代码并提出问题。 那么你的问题是什么? 消息数高达1000左右,因此获取新消息需要更多时间,是否有任何谓词通过使用这2个数组来获取新消息 【参考方案1】:

如果我理解正确,您需要将消息列表与服务器同步,并仅将新消息插入数据库中且数据库中尚不存在。

您可以使用 IN 语句。像下面这样:

NSMutableArray *arrayMessagesServer = [response objectForKey:@"messageList"];
arrayMessagesDB = [[NSMutableArray alloc]initWithArray:[self getMessagesFromDB]];

// this gives you an array of identifiers (NSString? as in your model): 
NSArray *existingIdentifiers = [arrayMessagesDB valueForKey:@"messageId"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"messageId NOT IN %@", existingIdentifiers];
NSArray *newMessages = [arrayMessagesServer filteredArrayUsingPredicate:predicate];

快速简单!

【讨论】:

现有标识符不是字符串。那么如何做到这一点 @PalchuriSudheerKumar 那么它是什么类?实施取决于具体事实。如果是NSNumber,几乎没有区别 我尝试了您的解决方案,但在第 4 行它崩溃了,原因是 *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“无法解析格式字符串”messageId NOT IN %@"' @PalchuriSudheerKumar 哦,对不起。我着急写了。正确的谓词应该是 [NSPredicate predicateWithFormat:@"NOT (messageId IN %@)", existingIdentifiers]

以上是关于如何使用 NSPredicate 从另一个 NSMutableArray 中过滤 NSMutableArray的主要内容,如果未能解决你的问题,请参考以下文章

NSM 可变数据。为啥保留计数 1 比我预期的要高?

如何使用 NSPredicate 加快数组搜索速度?

如何使用目标 C 将 JSON 响应存储到 NSPredicate 中?

核心数据:如何使用 NSPredicate 查找空字段

如何在不同的数据上使用 NSPredicate 和 NSPredicateEditor(多个谓词?)

NSPredicate - 使用两个条件进行评估