NSPredicate用于字符串长度依赖

时间:2013-08-21 14:30:54

标签: iphone ios objective-c nspredicate

我正在尝试从下面的另一个数组中过滤一个数组是我的代码片段

NSMutableArray *filteredArray = [[NSMutableArray alloc] initWithCapacity:1];
    [wordsArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
     {
         NSString *currentWord = (NSString *)obj;
         if(([currentWord length]>=4 && [currentWord length]<=6) && [currentWord rangeOfString:@" "].location == NSNotFound)
         {
             [filteredArray addObject:currentWord];
         }
     }];

我的代码完全符合我的预期。我觉得使用filteredArrayUsingPredicate:是比我的代码更优化的解决方案。如何为我的代码编写NSPredicate?

我跟了很多问题,但没有一个问题能给我准确的答案,用NSPredicate替换[currentWord length]>=4 && [currentWord length]<=6) && [currentWord rangeOfString:@" "].location == NSNotFound

3 个答案:

答案 0 :(得分:4)

尝试类似的谓词:

NSPredicate *p = [NSPredicate predicateWithFormat:@"length >= 4 AND length <= 6 AND NOT SELF CONTAINS ' '"];

答案 1 :(得分:2)

谓词是一个更清洁的解决方案。但它并不快(你说优化)。即使你重用了谓词!

我为我的2GHz i7 MacBook Pro写了一个小测试。解决方案:
1.000.000次过滤数组:

  • 每次新谓词:39.694秒
  • 重用谓词:17.784秒
  • 您的密码:2.174秒

差别很大,不是吗?

这是我的测试代码:

@implementation Test
- (void)test1
{
    int x = 0;
    NSArray *array = @[@"a", @"bb", @"ccc", @"dddd", @"eeeee", @"ffffff", @"ggggggg", @"hh hh", @"ii  ii"];
    for (int i = 0; i < 1000000; i++) {
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"length >= 4 AND length <= 6 AND NOT self CONTAINS ' '"];
        x += [array filteredArrayUsingPredicate:predicate].count;
    }
    NSLog(@"%d", x);
}

- (void)test2
{
    int x = 0;
    NSArray *array = @[@"a", @"bb", @"ccc", @"dddd", @"eeeee", @"ffffff", @"ggggggg", @"hh hh", @"ii  ii"];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"length >= 4 AND length <= 6 AND NOT self CONTAINS ' '"];
    for (int i = 0; i < 1000000; i++) {
        x += [array filteredArrayUsingPredicate:predicate].count;
    }
    NSLog(@"%d", x);
}

- (void)test3
{
    int x = 0;
    NSArray *array = @[@"a", @"bb", @"ccc", @"dddd", @"eeeee", @"ffffff", @"ggggggg", @"hh hh", @"ii  ii"];
    for (int i = 0; i < 1000000; i++) {
        NSMutableArray *filteredArray = [NSMutableArray array];
        [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
         {
             NSString *currentWord = (NSString *)obj;
             if(([currentWord length]>=4 && [currentWord length]<=6) && [currentWord rangeOfString:@" "].location == NSNotFound)
             {
                 [filteredArray addObject:currentWord];
            }
         }];
        x += filteredArray.count;
    }
    NSLog(@"%d", x);
}

答案 2 :(得分:0)

我认为这是Swift中最清晰的解决方案

NSPredicate(format: "str >= %@", ".{5}")