从NSMutableArray的元素检查0作为整数值

时间:2012-08-14 15:20:08

标签: objective-c ios xcode nsmutablearray nsarray

我有一个NSMutable数组,其元素插入如下:

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

我想删除数组中值为零或更低的元素。我尝试使用int值甚至是字符串值检查元素的值,但它总是传递'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 个答案:

答案 0 :(得分:3)

有几点。

  1. 尝试使用integerValue代替intValue
  2. 不要在数组中存储数字的字符串表示,而只需使用NSNumber。这就是它的用途。
  3. 避免在迭代数组时改变数组。
  4. 所以你用:

    创建你的数组
    [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];
    

答案 1 :(得分:2)

它正在跳过该元素,因为你在它之前删除了-5。 i递增到下一个值,该索引现在被前10个占用。可能有几种方法,但首先想到的是filteredArrayUsingPredicate:(参见NSArray documentation })。

答案 2 :(得分:2)

问题是这种方法使用了一个根本上有缺陷的逻辑。它错误地不会删除连续出现的0或负对象。原因是,当在for循环中检查“-5”时,它会通过测试,然后你将其删除,缩小数组,并移动其余的元素,使“0”现在位于“-5”。但是在for循环中,无论元素是否被删除,你都会推进循环变量(在这种情况下为i),所以现在'i'指出一个超过零。它不会被检查。解决方案:如果没有通过测试的连续元素(即将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];
    }
}

答案 3 :(得分:2)

我会选择NSPredicatepredicateWithBlock:。对于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);