我有一个有趣的挑战性问题。所以我有一个包含所有项目的可变数组。我有一个文本字段,如果有人输入这些项目,**可能有一个或两个这样的项目。**
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.
}
}
答案 0 :(得分:3)
你想要两组的交集:
NSMutableSet* intersectionSet = [NSMutableSet setWithArray:Allitems];
[intersectionSet intersectSet:[NSSet setWithArray:WORDS]];
NSArray* intersectionArray = [intersectionSet allObjects];
此intersectionArray
包含Allitems
和WORDS
中包含的项目。
allItems
和words
?
正如@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:@" "];
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
通常是一个不错的选择,因为测试集成员资格比使用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"
。