2

文字列の長さに基づいて文字列の配列を除外しようとしています。私はObjectiveCと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文字の単語のみを出力しますが、2番目のNSLogは配列全体を出力します。ここで何が欠けていますか?また、コードをクリーンアップ/改善するための一般的なポインタを歓迎します。

4

2 に答える 2

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];
于 2012-07-14T19:39:27.653 に答える
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"
    }]];
于 2012-07-14T19:25:02.350 に答える