2011-07-27 70 views
0

我有这段代码可以在文本文件中读取,并用换行符分隔单词。我想要做的是将所有单词读入数组,然后从该数组中选取所有六个字母的单词。从一个数组中获取特定长度的字符串

我在下面有这段代码,但它似乎是从for循环中生成一个错误。

此外,在阅读文本文件后,我是否必须发布它?

NSString* path = [[NSBundle mainBundle] pathForResource:@"newdict" ofType:@"txt"]; 

NSString* content = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL]; 

NSArray* allLinedStrings = [content componentsSeparatedByCharactersInSet: 
[NSCharacterSet newlineCharacterSet]]; 

int wordcount = [allLinedStrings count]; 
int i; 
NSMutableArray* sixLetterWords; 

for(i = 0 ; i < wordcount ; i++) 
{ 
    NSString* word = [allLinedStrings objectAtIndex: i]; 
    if (StrLength(word) == 6) 
     [sixLetterWords addObject:word]; 
} 
+1

对于将来的问题,给出特定的错误信息是一个好主意,而不是让人们猜测你看到的错误是什么,以及在什么行上。 – smorgan

+0

下次会记住这一点,非常感谢:) – kazuo

回答

3

比for循环更好的选择是fast enumeration

// Don't forget to actually create the mutable array 
NSMutableArray * sixLetterWords = [[NSMutableArray alloc] init]; 
for(NSString * word in allLinedStrings){ 
    if([word length] == 6) [sixLetterWords addObject:word]; 
}  

blocks-based enumerationenumerateObjectsUsingBlock:

NSMutableArray * sixLetterWords = [[NSMutableArray alloc] init]; 
[allLinedStrings enumerateObjectsUsingBlock:^(id word, NSUInteger idx, BOOL * stop){ 
    if([(NSString *)word length] == 6) [sixLetterWords addObject:word]; 
}]; 

也有可能性filter the array

NSArray * sixLetterWords = [allLinedStrings filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"length == 6" 

注意,这最后的选择给哟如果你想保留它,你必须保留它。有了这些,你就不必担心数组长度或明确的索引。它由数组处理。 Fast enumeration也如其名称所示,比简单for循环更快

您用来阅读文本文件到您的字符串,stringWithContentsOfFile:encoding:error:的方法,是不是newalloc,也不与copymutableCopy开始;因此,根据Cocoa memory management rules,您不拥有它并且不必释放它。 (如果你希望它在当前方法结束时仍然存在,你需要保留它。)

+0

真棒!非常感谢您的回答! – kazuo

1

您不需要释放您的文本文件,因为它将被自动发布。

编辑:

您需要的Alloc和初始化你的NSMutableArray ...

NSMutableArray* sixLetterWords = [[NSMutableArray alloc] init]; 

我在for循环有点不对,你有正确的第一次。

+0

试过这个,没有编译错误,但它停止应用程序,当它到达那里时,特别是在行['6LetterWords addObject:word];'说“线程1:编程接收信号:EXC_BAD_ACCESS”。 – kazuo

+0

阅读编辑... –

+0

此答案的第一部分错误。我 smorgan

0

没有想吹我自己的小号,CMFunctionalAdditions框架可以做到这一点更干净,同时:)

NSArray* sixLetterWords = [allLinedStrings filterWithPredicate:^BOOL(NSString* str) { 
    return [str length] == 6; 
}]; 
+0

感谢您分享您的工作!不过,你应该在类别方法名称上加上前缀。此外,此方法的名称与内置的['filteredArrayUsingPredicate:']非常相似(http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/NSArray.html# // apple_ref/doc/uid/20000137-BAJJDBEB),它采用'NSPredicate'对象而不是块。 –

+0

你是对的,除了最大的集合或最复杂的谓词外,filderedArrayUsingPredicate是最简单的解决方案。我认为苹果同时运行这个只是时间问题。 –

+0

我只是在谈论名称,而不是实现。无论何时将类别添加到框架类中,都必须确保Apple永远不会添加名称与您的名称相同的方法;传统的做法是使用前缀:'CM_filteredArrayUsingPredicate:'。 –

相关问题