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 に答える