在数组中查找字符串
Find string in array
我有一个有趣且具有挑战性的问题。所以我有一个可变数组,其中包含我所有的 项目。 我有一个文本字段,如果有人输入这些项目,**可能会有一两个项目。**
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 的特定词。 (如果文本字段包含来自 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.
}
}
你想要两组的交集:
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];
有多种方法可以做到这一点,每种方法各有利弊。让我们对每种情况都有以下(一致大写的)变量:
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
中的字符串与字典中的对象或键的字段进行匹配(以及 return 匹配的对象而不是字符串)。在这种情况下,要考虑的一种可能性是 NSDictionary
将要与对象匹配的单词映射到 return (也可以快速迭代 words
并测试字典中的成员资格) .
转换为字符串
并且,由于问题包括将匹配项转换为字符串:
[matchingItems componentsJoinedByString:@", "]
在示例中,这将导致字符串 "pear, cheese"
(如果使用集合,则可能是 "cheese, pear"
)。
我有一个有趣且具有挑战性的问题。所以我有一个可变数组,其中包含我所有的 项目。 我有一个文本字段,如果有人输入这些项目,**可能会有一两个项目。**
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 的特定词。 (如果文本字段包含来自 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.
}
}
你想要两组的交集:
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];
有多种方法可以做到这一点,每种方法各有利弊。让我们对每种情况都有以下(一致大写的)变量:
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
中的字符串与字典中的对象或键的字段进行匹配(以及 return 匹配的对象而不是字符串)。在这种情况下,要考虑的一种可能性是 NSDictionary
将要与对象匹配的单词映射到 return (也可以快速迭代 words
并测试字典中的成员资格) .
转换为字符串
并且,由于问题包括将匹配项转换为字符串:
[matchingItems componentsJoinedByString:@", "]
在示例中,这将导致字符串 "pear, cheese"
(如果使用集合,则可能是 "cheese, pear"
)。