查看NSDictionary密钥是否在另一个NSArray中

时间:2014-09-17 12:28:24

标签: ios objective-c uitableview nsarray nsdictionary

Database (
    {
        to = (NSString *)
        from = (NSString *)
        subject = (NSString *)
        uid = int
        body = (NSString *)
    }, { ...
)

Downloaded (
    {
        to = (NSString *)
        from = (NSString *)
        subject = (NSString *)
        uid = int
        body = (null)
    }, { ...
)

我立即从我的数据库中将NSArray大约200个NSDictionayUITableView个对象加载到我的NSArray中,然后下载NSDictionary个相同结构的NSDictionary NSArray但没有身体。

问:如何通过匹配密钥:“uid”来查看所有200个已下载{{1}}以查看它是否已存在于我的数据库{{1}}中?

3 个答案:

答案 0 :(得分:3)

这应该可以解决问题:

NSArray *arrayOfNew = [arrayDownload filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"NOT (uid IN %@)", [arrayDataBase valueForKey:@"uid"]];

使用此示例数据进行测试,如果有人想测试它:

NSDictionary *dictionary0 = @{@"to":@"0",@"from":@"0",@"uid":@(0), @"body":@"0"};
NSDictionary *dictionary1 = @{@"to":@"1",@"from":@"1",@"uid":@(1), @"body":@"0"};
NSDictionary *dictionary2 = @{@"to":@"2",@"from":@"2",@"uid":@(2), @"body":@"0"};
NSDictionary *dictionary3 = @{@"to":@"3",@"from":@"3",@"uid":@(3), @"body":@"0"};

NSDictionary *dictionary4 = @{@"to":@"4",@"from":@"4",@"uid":@(2)};
NSDictionary *dictionary5 = @{@"to":@"5",@"from":@"5",@"uid":@(5)};

NSArray *arrayDataBase = @[dictionary0, dictionary1, dictionary2, dictionary3];
NSArray *arrayDownload = @[dictionary4, dictionary5];

//So the dictionary4 shouldn't be kept, and dictionary5 should be kept.
NSArray *arrayNew = [arrayDownload filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"NOT (uid IN %@)", [arrayDataBase valueForKey:@"uid"]]];
NSLog(@"arrayNew: %@", arrayNew);

输出:

arrayNew: (
        {
        from = 5;
        to = 5;
        uid = 5;
    }

答案 1 :(得分:1)

使用此代码,您可以迭代两个名为" Downloaded"和"数据库"并检查他们的uid是否匹配。我不确定您是否正在寻找更优雅的解决方案。

for (NSDictionary *dictDownloaded in Downloaded) {
    for (NSDictionary *dictDatabase in Database) {
        if ([dictDownloaded objectForKey:@"uid"] == [dictDatabase objectForKey:@"uid"]) {
            NSLog(@"Object with uid: %d is in database", [[dictDownloaded objectForKey:@"uid"] intValue]);
        }
    }
}

答案 2 :(得分:0)

小心嵌套循环:) 如果您使用Arturo的示例(有效!)并下载1000条消息,您将有可能O(n * m)= 1000 * 200 = 200.000"计算步骤"

Larme的尝试非常优雅(我喜欢谓词!)但很难预测它将用于执行的时间,因为它全部封装在NSPredicate中。

因此,基于Larme的示例数据的另一种尝试是使用带有uid的字典作为快速查找的关键字。

    NSMutableDictionary *databaseLookupDictionary = [[NSMutableDictionary alloc]init];
    databaseLookupDictionary[@(0)] = @{@"to":@"0",@"from":@"0",@"uid":@(0), @"body":@"0"};
    databaseLookupDictionary[@(1)] = @{@"to":@"1",@"from":@"1",@"uid":@(1), @"body":@"0"};
    databaseLookupDictionary[@(2)] = @{@"to":@"2",@"from":@"2",@"uid":@(2), @"body":@"0"};
    databaseLookupDictionary[@(3)] = @{@"to":@"3",@"from":@"3",@"uid":@(3), @"body":@"0"};


    /* your download code */

    // example data 
    NSMutableArray *downloadedData = [[NSMutableArray alloc]init];
    [downloadedData addObject: @{@"to":@"0",@"from":@"0",@"uid":@(3)}];
    [downloadedData addObject: @{@"to":@"0",@"from":@"0",@"uid":@(4)}];

    for(NSDictionary *downloadDataDict in downloadedData)
    {
        // will be executed for message #4
        if(![databaseLookupDictionary.allKeys containsObject:downloadDataDict[@"uid"]])
        {
            NSLog(@"Unknown message data found: %@", downloadDataDict);
        }
    }

这是以线性时间(O(n)* O(1))运行所以你应该对性能很好。但请记住:如果您的消息数据库数量增加,您应该考虑直接在CoreData中进行搜索。