通过锚定搜索第二,第三等单词对字符串数组进行排序

时间:2013-03-21 15:54:11

标签: ios objective-c sorting nsarray nspredicate

我的意思是有一个包含如下字样的数组:

@[@"Hellobla", @"Hello Kitty", @"Hello Kitty Bla", @"Bla apukitty", @"Bla helkitty"]

我需要对它们进行排序,就像锚定由空格@" "分隔的所有单词一样。

如果我输入"Hel" - 我会看到@"Hellobla", @"Hello Kitty Bla", @"Bla helkitty"

如果我输入"kit" - 我会看到@"Hello Kitty Bla", @"Hello Kitty"

如果我输入"bla" - 我会看到@"Hello Kitty Bla", @"Bla apukitty", @"Bla helkitty"

等:)

我在块返回数组中执行:

    // arrayWithData - All Words
    // searchWord - Text i try to search with
    // arrayToWrite - array to return with words
    // arrayToCompare - array with words already added whitch first NSPredicate *beginPredicate = [NSPredicate predicateWithFormat:@"self BEGINSWITH[cd] %@", //searchText];

beginMatch = [self.objects filteredArrayUsingPredicate:beginPredicate];

   sortedWithSecondWordArray = ^(NSArray * arrayWithData,
                                  NSString * searchWord,
                                  NSMutableArray *arrayToWrite,
                                  NSArray * arrayToCompare) {

        NSString *space = @" ";

        for (__strong NSString *string in arrayWithData) {
            NSString *staticString = string; 
            while ([string rangeOfString:space].location != NSNotFound) {
                NSRange range = NSMakeRange(0, [string rangeOfString:space].location);

                NSString *keyword = [[string stringByReplacingCharactersInRange:range withString:@""] trim];

                if (keyword.length > 0
                    && [keyword rangeOfString:searchWord options:NSAnchoredSearch].location != NSNotFound
                    && ![arrayToCompare containsObject:staticString]
                    && ![arrayToWrite containsObject:staticString]) {

                    [arrayToWrite addObject:staticString];
                }
                string = keyword;
            };
        }
        return arrayToWrite;
    };

它可以工作,但如果在我的Array 2000字符串中它可能超过10k。它非常可怕。如何优化呢?

2 个答案:

答案 0 :(得分:2)

如果我已正确理解您的问题,那么您是否希望匹配包含以搜索字符串开头的单词的任何字符串?

使用正则表达式的NSPredicate可以使用\b字边界锚点来执行此操作。

NSArray *data = @[@"Hellobla", @"Hello Kitty", @"Hello Kitty Bla", @"Bla apukitty", @"Bla helkitty"]; 

NSString *searchString = @"Hel"; // Change to other strings

NSString *anchoredPattern = [NSString stringWithFormat: @".*\\b%@.*", searchString];

NSPredicate *anchoredPred = [NSPredicate predicateWithFormat: @"SELF MATCHES[cd] %@", anchoredPattern];

NSArray *filtered = [data filteredArrayUsingPredicate:anchoredPred];

它产生你所追求的结果,可能的例外是它在结果中包含“Hello Kitty”和“Hello Kitty Bla”。

如果那不是你想要的,你可能需要再次过滤结果,以排除作为数组中其他字符串的子串的字符串。

答案 1 :(得分:0)

你说你的搜索是有效的(它应该做的不是问题中的超级清晰),但是你关注的是速度。它是否明显缓慢,或者你预测它会是什么?

字符串计数,而不是字节数,是速度的因素。 2000年是大人物,但我的直觉是使用蛮力将足够快。

或者,优化搜索是一个很大的主题,但是可以总结大多数解决方案如下:构建索引。例如Check out 'Tries'