5

ViewDidLoad我在方法中有一个包含以下元素的数组

inputArray = [NSMutableArray arrayWithObjects:@"car", @"bus", @"helicopter", @"cruiz", @"bike", @"jeep", nil];

我有另一个UITextField用于搜索元素。所以一旦我输入一些东西,UITextField我想检查该字符串是否存在于“inputArray”中。如果它与 inputArray 中的元素不匹配,则从 inputArray 中删除相应的元素。

 for (NSString* item in inputArray)
   {
        if ([item rangeOfString:s].location == NSNotFound) 
        {
            [inputArray removeObjectIdenticalTo:item];//--> Shows Exception
            NSLog(@"Contains :%@",containsAnother);
        }

  }

但此代码显示异常,与“removeobject:”有关

例外 :

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSCFConstantString rangeOfString:options:range:locale:]: nil argument'
*** First throw call stack:
`
4

8 回答 8

10

在快速枚举中,您不能修改集合。

枚举器对象变得恒定且不可变。

如果你想对阵列进行更新

你应该喜欢这样:

NSMutableArray *inputArray = [NSMutableArray arrayWithObjects:@"car", @"bus", @"helicopter", @"cruiz", @"bike", @"jeep", nil];
NSString *s=@"bus";

for (int i=inputArray.count-1; i>-1; i--) {
    NSString *item = [inputArray objectAtIndex:i];
    if ([item rangeOfString:s].location == NSNotFound) {
        [inputArray removeObject:item];
    }
}

编辑:

上面的工作与此类似:

NSArray *array=[inputArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF CONTAINS[c] %@",s]]; 
于 2013-04-15T13:11:14.543 回答
10

您可以使用以下代码

for (int i=0;i<[inputArray count]; i++) {
        NSString *item = [inputArray objectAtIndex:i];
        if ([item rangeOfString:s].location == NSNotFound) {
            [inputArray removeObject:item];
            i--;
        }
    }
于 2013-04-15T13:14:33.770 回答
0

那需要是一个NSMutableArray. 您不能修改NSArray曾经创建的内容(除非重新开始)。

改变这个:

inputArray = [NSArray arrayWithObjects:@"car", @"bus", @"helicopter", @"cruiz", @"bike", @"jeep", nil];

对此:

inputArray = [NSMutableArray arrayWithObjects:@"car", @"bus", @"helicopter", @"cruiz", @"bike", @"jeep", nil];

并将属性更改为 NSMutableArray :

@property(nonatomic, strong) NSMutableArray *inputArray;
于 2013-04-15T13:07:07.927 回答
0

你的s问题中的可能为零。所以你得到了例外。请检查一下。

于 2013-04-15T13:12:59.993 回答
0

这是我喜欢使用的干净解决方案。您定义一个 NSArray 类别来扩展它并创建一个map方法。此方法根据您在块中返回的内容创建一个新的 NSArray:

@interface NSArray (BlockExtensions)
/*! 
 Invokes block once for each element of self, returning a new array containing the
 values returned by the block.
 */
- (NSArray *)map:(id (^)(id obj))block;

@end

@implementation NSArray (BlockExtensions)

- (NSArray *)map:(id (^)(id obj))block
{
    return [self mapWithOptions:0 usingBlock:^id(id obj, NSUInteger idx) {
        return block(obj);
    }];
} 

- (NSArray *)mapWithOptions:(NSEnumerationOptions)options usingBlock:(id (^)(id obj, NSUInteger idx))block
{
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:[self count]];
    [self enumerateObjectsWithOptions:options usingBlock:^(id obj, NSUInteger idx, BOOL *stop)     {

        id newobj = block? block(obj, idx) : obj;
        if (newobj)
            [array addObject:newobj];
    }];
    return array;
}
    @end

该块将为原始数组中的每个项目调用一次,将此对象作为参数传递:

NSArray *newArray = [inputArray map:^id(NSString *item) {
    if ([item rangeOfString:s].location == NSNotFound) {
        return item;
    }
    return nil;
}];

newArray将包含您过滤掉的项目!

于 2013-04-15T13:16:22.277 回答
0

使用以下代码。(此代码用于基于输入字符串/文本的过滤器数组UITextField

取两个NSMutableArray并将一个数组添加到另一个数组ViewDidLoad,例如,

self.listOfTemArray = [[NSMutableArray alloc] init]; // array no - 1
self.ItemOfMainArray = [[NSMutableArray alloc] initWithObjects:@"YorArrayList", nil]; // array no - 2 

[self.listOfTemArray addObjectsFromArray:self.ItemOfMainArray]; // add 2array to 1 array

并编写以下 UISearchBar 的委托方法

- (BOOL) textFieldDidChange:(UITextField *)textField
 {
        NSString *name = @"";
        NSString *firstLetter = @"";

    if (self.listOfTemArray.count > 0)
         [self.listOfTemArray removeAllObjects];

        if ([searchText length] > 0)
        {
                for (int i = 0; i < [self.ItemOfMainArray count] ; i = i+1)
                {
                        name = [self.ItemOfMainArray objectAtIndex:i];

                        if (name.length >= searchText.length)
                        {
                                firstLetter = [name substringWithRange:NSMakeRange(0, [searchText length])];
                                //NSLog(@"%@",firstLetter);

                                if( [firstLetter caseInsensitiveCompare:searchText] == NSOrderedSame )
                                {
                                    // strings are equal except for possibly case
                                    [self.listOfTemArray addObject: [self.ItemOfMainArray objectAtIndex:i]];
                                    NSLog(@"=========> %@",self.listOfTemArray);
                                }
                         }
                 }
         }
         else
         {
             [self.listOfTemArray addObjectsFromArray:self.ItemOfMainArray ];
         }

        [self.tblView reloadData];
}

}

输出显示在您的Console.

于 2013-04-15T13:20:42.653 回答
0

正如其他人所说,您不能在枚举数组时对其进行变异。做你想做的事情并保持快速枚举的便利的最简单方法是复制数组。

for (NSString* item in [inputArray copy]) {
   ...
}
于 2013-04-15T13:21:03.003 回答
0

向 Anoop +1 指出您可以使用filteredArrayUsingPredicate. 因此,如果您想根据 中的匹配项创建一个新数组inputArray,您还可以使用类似:

NSArray *matchingArray = [inputArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF contains[c] %@", s]];

或者,假设这inputArray是一个NSMutableArray,您可以简单地使用这一行过滤数组:

[inputArray filterUsingPredicate:[NSPredicate predicateWithFormat:@"SELF contains[c] %@", s]];

或者,如果你喜欢块:

[inputArray filterUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
    return ([evaluatedObject rangeOfString:s].location != NSNotFound);
}]];
于 2013-04-15T14:53:57.317 回答