NSMutableArray removeObjectAtIndex用法

时间:2012-07-14 19:21:25

标签: objective-c nsmutablearray

我正在尝试根据长度过滤出一串字符串。我对Objective C和OOP完全不熟悉。

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]);
}

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

2 个答案:

答案 0 :(得分: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];

答案 1 :(得分: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"
    }]];