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

Posted

技术标签:

【中文标题】如何使用 NSPredicate 加快数组搜索速度?【英文标题】:How can I speed up my array search with an NSPredicate? 【发布时间】:2012-04-24 09:42:27 【问题描述】:

我有一个类别数组和另一个类别 ID 数组。我想提取具有匹配 ID 的类别。目前,我的代码看起来有点像这样:

- (NSArray *)categoriesFromArray:(NSArray *)categories withIDs:(NSArray *)categoryIDs 
    NSMutableArray *categoriesWithIDs = [NSMutableArray array];

    for (SGBCategory *category in categories) 
        for (NSNumber *categoryID in categoryIDs) 
            if ([category.categoryID isEqual:categoryID]) 
                [categoriesWithIDs addObject:category];
                break;
            
        
    

    return categoriesWithIDs;

Ewww,我知道。所以我想做的是像SELECT * FROM categories WHERE categories.categoryID in (categoryIDs) 在SQL 中所做的那样。我认为 NSPredicate 是表达这类事情的客观 c 方式,但我不知道如何让它做我想做的事。

【问题讨论】:

【参考方案1】:
return [categories filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"categoryID IN %@", categoryIDs]];

不过,我不知道它会更快。它基本上必须和你的代码做同样的事情,外加一个谓词。

您可以通过从categoryIDs 创建一个NSSet 并使用-containsObject: 来改进您的代码,而不是循环遍历categoryIDs 并手动调用-isEqual:

【讨论】:

【参考方案2】:

我不确定谓词,但立即优化是将您的类别 ID 放在一个集合中

- (NSArray *)categoriesFromArray:(NSArray *)categories withIDsFromSet:(NSSet *)categoryIDs 
    NSMutableArray *categoriesWithIDs = [NSMutableArray array];

    for (SGBCategory *category in categories) 
        if ([categoryIDS containsObject: [category categoryID]])
        
            [categoriesWithIDs addObject:category];
        
    
    return categoriesWithIDs;

编辑

如果你想继续使用你的旧方法,那么修改它:

- (NSArray *)categoriesFromArray:(NSArray *)categories withIDs:(NSArray *)categoryIDs 

    return [self categoriesFromArray: categories withIDsFromSet: [NSSet setWithArray: categoryIDs]];

如果categoriescategoryIDs 较大,这仍将比您原来的方法高效得多。

【讨论】:

谢谢 - 虽然这改变了方法的签名,所以它对我们不适用。 @Simon:这是一种新方法,因此不会更改签名。不过,我会稍微修改一下答案以提供帮助。【参考方案3】:
NSPredicate* searchPredicate = [NSPredicate predicateWithFormat:@"categoryID == %f", categoryID];
    NSArray *categoriesWithIDs =[categories filteredArrayUsingPredicate:searchPredicate];
    return categoriesWithIDs;

这就是你会如何做你想做的事。假设类别 id 是浮点数。根据需要更改 %f,就像使用 NSLog 一样。

【讨论】:

以上是关于如何使用 NSPredicate 加快数组搜索速度?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL - 如何使用地理位置数据加快搜索速度?

具有 10+ 百万行的 MySQL 表 - 如何使用索引加快搜索速度?

索引如何加快搜索速度? [复制]

使用 NSPredicate 和数组进行 cloudKit 搜索

使用 NSPredicate 搜索字符串数组

使用 NSPredicate 搜索/过滤自定义类数组