在数组中查找字符串

时间:2015-07-31 07:38:20

标签: objective-c arrays nsmutablearray

我有一个有趣的挑战性问题。所以我有一个包含所有项目的可变数组。我有一个文本字段,如果有人输入这些项目,**可能有一个或两个这样的项目。**

items= [[NSArray alloc]initWithObjects:@"apple", @"orange", @"pear", nil];

items2= [[NSArray alloc]initWithObjects:@"cheese", @"milk", @"eggs", nil];

Allitems= [NSMutableArray array];
[Allitems addObjectsFromArray:items];
[Allitems addObjectsFromArray:items2];

NSArray*WORDS =[Textfield componentsSeparatedByString:@" "];

我正在尝试检测** Allitems 中的哪些特定字词在文本字段中。 (如果textfield包含ALLitems中的任何字符串,我如何找到具体的字符串?**

for (int i = 0; i < [Allitems count]; i++)
{
      NSString *grabstring;
      grabstring=[Allitems objectAtIndex:i];

      if (textfield isEqualto:grabstring){
        ?????
           pull that specific string from allitems.


     }
}

2 个答案:

答案 0 :(得分:3)

你想要两组的交集:

NSMutableSet* intersectionSet = [NSMutableSet setWithArray:Allitems];
[intersectionSet intersectSet:[NSSet setWithArray:WORDS]];
NSArray* intersectionArray = [intersectionSet allObjects];

intersectionArray包含AllitemsWORDS中包含的项目。

顺便说一句,为什么要以非标准和不一致的方式对变量名称进行大写?为什么不只是allItemswords

正如@Arkku建议的那样:切换阵列会更好。在你的例子中它并不重要,但是如果Allitems(非常)大,你可以节省(大量)内存和CPU使用:

NSMutableSet* intersectionSet = [NSMutableSet setWithArray:WORDS];
[intersectionSet intersectSet:[NSSet setWithArray:Allitems]];
NSArray* intersectionArray = [intersectionSet allObjects];

答案 1 :(得分:1)

有各种各样的方法,每种方式都有不同的优点和缺点。对于每种情况,我们都有以下(始终大写)变量:

NSArray *allItems = @[ @"apple", @"orange", @"pear", @"cheese", @"milk", @"egg" ];
NSString *textFieldText = @"CHEESE ham pear";
NSArray *words = [textFieldText.lowercaseString componentsSeparatedByString:@" "];

NSPredicate

NSArray *matchingItems = [allItems filteredArrayUsingPredicate:
                          [NSPredicate predicateWithFormat:@"SELF IN %@", words]];

这可能是最短的(以代码为单位)方式,但如果allItems可能很长,因为它需要遍历所有这些方式,这可能不是最高效的。

迭代

当然,您也可以简单地遍历集合并手动进行匹配:

NSMutableArray *matchingItems = [NSMutableArray array];
for (NSString *item in allItems) {
    if ([words containsObject:item]) {
        [matchingItems addObject:item];
    }
}

再次需要遍历所有allItems(尽管如果所有单词都匹配,你可以break迭代。)

除了for循环之外,还有许多其他迭代方法,例如enumerateObjectsUsingBlock:,但它们在这里不太可能有任何优势。

的NSSet

对于这种匹配,

NSSet通常是一个不错的选择,因为测试集成员资格比使用NSArray更快。但是,如果使用最简单的方法intersetSet:(在NSMutableSet中),必须注意不要无意中创建一个大的可变集,只丢弃其大部分项目。

如果allItems的顺序无关紧要,最好的方法是将它从数组更改为集合并始终保持该集合,即不是创建数组allItems,你会创建一个NSSet

NSSet *setOfAllItems = [NSSet setWithArray:allItems];

或者如果它需要是可变的:

NSMutableSet *setOfAllItems = [NSMutableSet set];
[setOfAllItems addObjectsFromArray:items1];
[setOfAllItems addObjectsFromArray:items2];

然后,当你有了这个集合时,你创建了一个临时的可变集合words(可能总是较小的集合):

NSMutableSet *setOfMatches = [NSMutableSet setWithArray:words];
[setOfMatches intersectSet:setOfAllItems];
NSArray *matchingItems = setOfMatches.allObjects;

如果setOfAllItems很大,这可能是性能最佳的解决方案,但请注意,匹配将需要精确。其他方法更容易适应诸如将words中的字符串与对象字段或字典中的键匹配(并返回匹配的对象而不是字符串)之类的事情。在这种情况下,可以考虑的一种可能性是NSDictionary映射要与要返回的对象匹配的单词(也快速迭代words并测试字典中的成员资格)。

转换为字符串

并且,因为问题包括将匹配转换为字符串:

[matchingItems componentsJoinedByString:@", "]

在示例中,如果使用集合,则会产生字符串"pear, cheese"(或者可能"cheese, pear"