0

次のように要素が挿入された NSMutable 配列があります。

[availableSeatsArray addObject:[NSString stringWithString:num_available]];

ゼロ以下の値を持つ配列内の要素を削除したい。int 値と string 値を使用して要素の値を確認しようとしましたが、常に「0」要素のケースを渡します。以下の前後のアレイのコンソール出力。

for (int i=0;i<[availableSeatsArray count]; i++) {
        if ([[availableSeatsArray objectAtIndex:i] intValue] <= 0 || ([[availableSeatsArray objectAtIndex:i] isEqualToString:@"0"])) {
            NSLog(@"Removed index: %d", [[availableSeatsArray objectAtIndex:i] intValue]);
            [availableSeatsArray removeObjectAtIndex:i];
        }
}

コンソール出力:

Available array: (
    "-2",
    10,
    5,
    "-5",
    0,
    10,
    10,
)
2012-08-14 11:13:28:002 -[dmbAddReservation viewWillAppear:] [Line 1074] Removed index: -2
2012-08-14 11:13:28:004 -[dmbAddReservation viewWillAppear:] [Line 1074] Removed index: -5
2012-08-14 11:13:28:006 -[dmbAddReservation viewWillAppear:] [Line 1083] Available array: (
    10,
    5,
    0, // I cannot explain why this element was not removed
    10,
    10,
)
4

4 に答える 4

3

いくつかのポイント。

  1. integerValueの代わりに使用してみてくださいintValue
  2. 数値の文字列表現を配列に格納するのではなく、NSNumber代わりに an を使用します。それがそのためです。
  3. 反復処理中に配列を変更しないでください。

したがって、次のように配列を作成します。

[availableSeatsArray addObject:[NSNumber numberWithInteger:[num_available integerValue]]];

そして、それらを除外できます(ブロックベースの列挙方法を使用していることに注意してください):

__block NSMutableArray *itemsToRemove;
[availableSetsArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    if ([obj integerValue] == 0]) {
        [itemsToRemove addObject:obj]
    }
}];

// Now that you've selected which objects to remove you can actually remove them.
[availableSetsArray removeObjectsInArray:itemsToRemove];
于 2012-08-14T15:36:16.657 に答える
2

その前に -5 を削除しているため、その要素をスキップしています。 i次の値にインクリメントし、そのインデックスは現在最初の 10 で占められています。これにはおそらくいくつかの方法がありますが、最初に頭に浮かぶのはfilteredArrayUsingPredicate:( NSArray のドキュメントを参照)。

于 2012-08-14T15:30:09.573 に答える
2

問題は、このアプローチが根本的に欠陥のあるロジックを使用していることです。0 または負のオブジェクトが連続して出現しても、誤って削除されません。その理由は、for ループで「-5」をチェックすると、テストに合格し、それを削除して配列を縮小し、残りの要素をシフトして、「0」が代わりに配置されるようにするためです。 「-5」。しかし、for ループでは、要素が削除されたかどうかに関係なく、ループ変数 (この場合は i) を進めるため、'i' は 0 の 1 つ後ろを指します。そして、それはチェックされません。解決策: テストに合格する連続した要素がない場合にのみ、ループ変数を増やします (つまり、if を while に変更します)。

for (int i = 0; i < [availableSeatsArray count]; i++) {
    while ([[availableSeatsArray objectAtIndex:i] intValue] <= 0
       || ([[reservatiomAvailableArray objectAtIndex:i] isEqualToString:@"0"])) {
        NSLog(@"Removed index: %d", [[availableSeatsArray objectAtIndex:i] intValue]);
        [availableSeatsArray removeObjectAtIndex:i];
    }
}
于 2012-08-14T15:31:09.197 に答える
2

NSPredicate私はとに行きpredicateWithBlock:ます。NSMutableArray の場合filterUsingPredicate:、新しいオブジェクトを作成せずに不要なオブジェクトを配列から削除するメソッドを使用できます。次のコードはそれを行います:

NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"0",@"1",@"2", @"-50", nil];
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(NSString* evaluatedObject, NSDictionary *bindings) {
    return [evaluatedObject compare:@"0" options:NSNumericSearch] > 0;
}];
[arr filterUsingPredicate:predicate];
NSLog(@"%@", arr);
于 2012-08-14T15:41:39.477 に答える