1

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

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?

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

4

3 回答 3

4

尝试如下谓词:

NSPredicate *p = [NSPredicate predicateWithFormat:@"length >= 4 AND length <= 6 AND NOT SELF CONTAINS ' '"];
于 2013-08-21T14:35:52.440 回答
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);
}
于 2013-08-21T14:55:56.683 回答
0

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

NSPredicate(format: "str >= %@", ".{5}")
于 2019-08-06T10:18:04.200 回答