2012-07-14 57 views
2

我想根据它们的长度过滤出一个字符串数组。一般来说,我完全不熟悉Objective C和OOP。NSMutableArray removeObjectAtIndex用法

wordList=[[stringFile componentsSeparatedByCharactersInSet:[NSCharacterSetnewlineCharacterSet]] mutableCopy]; 
for (int x=0; x<[wordList count]; x++) { 
    if ([[wordList objectAtIndex:x] length] != 6) { 
     [wordList removeObjectAtIndex:x]; 
    }else { 
     NSLog([wordList objectAtIndex:x]); 
    } 
} 

for (int x=0; x<[wordList count]; x++) { 
    NSLog([wordList objectAtIndex:x]); 
} 

NSLog在else语句中只输出6个字母的单词,但第二个NSLog输出整个数组。我在这里错过了什么?还有任何通用的指针来清理/改进代码,我们感激不尽。

回答

2

您的代码存在的问题是,当您删除索引为x的项目并移动到下一个索引x++时,从未检查过在x+1处的项目。

过滤可变数组的最佳方法是使用filterUsingPredicate:方法。这里是你如何使用它:

wordList=[[stringFile 
    componentsSeparatedByCharactersInSet:[NSCharacterSetnewlineCharacterSet]] 
    mutableCopy]; 
[wordList filterUsingPredicate: 
    [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary * bindings) { 
     return [evaluatedObject length] == 6; // YES means "keep" 
    }]]; 
+0

好吧,这是有道理的。我尝试在if长度!= 6语句中添加一个x--,这也适用。既然我在学习,我会用你的方法,但出于好奇,x有什么问题吗? – user1418214 2012-07-14 19:35:33

+0

@ user1418214添加'x - '没有什么问题,但更典型的解决方案是使用'while'代替for',并将'x ++'增量放入'else'分支。 – dasblinkenlight 2012-07-14 19:40:29

+0

使用谓词方法,'NSDictionary * binding'部分如何影响程序? – user1418214 2012-07-14 19:46:05

3

取决于你觉得什么是最容易理解的,你既可以在阵列与谓词过滤或迭代这个数组并删除对象。你应该选择你最容易理解和维护的方法。

过滤器使用谓词

谓词是滤波阵列或集合的一个非常简洁的方式,但是这取决于你的背景,他们可能会觉得奇怪使用。你可以过滤你的阵列是这样的:

NSMutableArray * wordList = // ... 
[wordList filterUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) { 
    NSString *word = evaluatedObject; 
    return ([word length] == 6); 
}]]; 

枚举和删除

同时枚举它不能修改数组,但你可以记录所有要删除,并删除他们都在哪些项目列举了整个阵列后的一个批次,如下所示:

NSMutableArray * wordList = // ... 
NSMutableIndexSet *indicesForObjectsToRemove = [[NSMutableIndexSet alloc] init]; 
[wordList enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 
    NSString *word = obj; 
    if ([word length] != 6) [indicesForObjectsToRemove addIndex:idx]; 
}]; 
[wordList removeObjectsAtIndexes:indicesForObjectsToRemove];