美文网首页
数组遍历自身的同时删除元素

数组遍历自身的同时删除元素

作者: 下雨就好 | 来源:发表于2017-06-12 22:54 被阅读123次

我们在遍历可变数组时,最好不要做删除数组中元素的操作。

因为删除操作可能会引起数组容量的变化,导致数组越界等问题。

以前在使用for循环遍历的时候遇到过这个问题。

当时的做法是使用enumerateObjectsUsingBlock:,但是这次又遇到这个问题时,顺便好好的测试了一下for、for in、enumerateObjectsUsingBlock:。

实验结果如下:

NSMutableArray*array = [NSMutableArrayarrayWithArray:@[@"1",@"2",@"3",@"4",@"5"]];[array enumerateObjectsUsingBlock:^(id_Nonnull obj, NSUInteger idx,BOOL* _Nonnull stop) {if([obj isEqualToString:@"3"]) {        [array removeObject:obj];    }}];NSLog(@"%@",array);// 输出结果:(1,2,4,5)

1

2

3

4

5

6

7

8

9

1

2

3

4

5

6

7

8

9

结果正常。

使用for in:

NSMutableArray *array= [NSMutableArray arrayWithArray:@[@"1",@"2",@"3",@"4",@"5"]];for(NSString *objinarray) {if([obj isEqualToString:@"3"]) {        [arrayremoveObject:obj];    }}NSLog(@"%@",array);

1

2

3

4

5

6

7

1

2

3

4

5

6

7

结果出现崩溃,信息如下:

2016-11-1122:48:06.886Solutions[15297:2231002] *** Terminating app duetouncaughtexception'NSGenericException', reason:'*** Collection <__NSArrayM: 0x1001060b0> was mutated while being enumerated.'*** First throw call stack:(0CoreFoundation0x00007fff929c14f2__exceptionPreprocess +1781libobjc.A.dylib0x00007fff8fcb2f7eobjc_exception_throw +482CoreFoundation0x00007fff92a2815c__NSFastEnumerationMutationHandler +3003Solutions0x0000000100000d1cmain +5084libdyld.dylib0x00007fff90cd05adstart +1)libc++abi.dylib: terminatingwithuncaughtexceptionoftypeNSException

1

2

3

4

5

6

7

8

9

10

1

2

3

4

5

6

7

8

9

10

使用for:

NSMutableArray *array= [NSMutableArray arrayWithArray:@[@"1",@"2",@"3",@"4",@"5"]];for(inti =0; i

1

2

3

4

5

6

7

8

9

1

2

3

4

5

6

7

8

9

结果正常,可能是苹果对普通的for循环内部的处理做了修正,以前这样写是会报错的。

其实,最正确与稳妥的方案,是对数组逆序遍历,然后再删除元素就没有问题了。

例如for in的逆序遍历:

NSMutableArray *array= [NSMutableArray arrayWithArray:@[@"1",@"2",@"3",@"4",@"5"]];for(NSString *obj inarray.reverseObjectEnumerator) {if([obj isEqualToString:@"3"]) {        [arrayremoveObject:obj];    }}NSLog(@"%@",array);// 输出结果:(1,2,4,5)

1

2

3

4

5

6

7

8

1

2

3

4

5

6

7

8

使用

NSMutableArray*array = [NSMutableArrayarrayWithArray:@[@"1",@"2",@"3",@"4",@"5"]];[array enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id_Nonnull obj, NSUInteger idx,BOOL* _Nonnull stop) {if([obj isEqualToString:@"3"]) {                [array removeObject:obj];            }        }];NSLog(@"%@",array);// 输出结果:(1,2,4,5)

1

2

3

4

5

6

7

8

9

1

2

3

4

5

6

7

8

9

关于for 的逆序

NSMutableArray *array= [NSMutableArray arrayWithArray:@[@"1",@"2",@"3",@"4",@"5"]];for(inti =array.count -1; i >=0; i--) {    NSString *obj =array[i];if([obj isEqualToString:@"3"]) {        [arrayremoveObject:obj];    }}NSLog(@"%@",array);// 输出结果:(1,2,4,5)

1

2

3

4

5

6

7

8

9

1

2

3

4

5

6

7

8

9

以前做Java开发的时候,也遇到过这种遍历删除元素的,那时候的做法是在遍历,删除元素后做一次i–操作。

现在想来,也可以逆序遍历然后直接删除即可。

====================================

或者楼主可以用 while 循环语句来做。

例如:

while(array.count>0)

{

obj = [array objectAtIndex:0];

//判断处理

//remove

[array removeObjectAtIndex:0];

}

=========================================

可以用NSPredicate来完成:

NSArray *sourceArray = @[];

NSArray *whatYouNeedArray = [sourceArray filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {

return ![evaluatedObject shouldBeDeleted];

}]];

whatYouNeedArray就是你要的array,已经去除掉该删除的项。

=======================================

一般不要这样做,如果要删除,一定要在删除之后,break.

Oc语言中有三种遍历数组的方式,一是传统的for循环,二是for-in循环,三是迭代器。其中,第一种方式的效率最低。第二种遍历方法如下,第三种使用比较少,你可以自己去网上看下。

for (NSString * str in names)

{

if ([str isEqualTo: @"something"]){

[names removeObject: str];

break;//一定要有break,否则会出错的。

}

}

相关文章

  • 数组遍历自身的同时删除元素

    我们在遍历可变数组时,最好不要做删除数组中元素的操作。 因为删除操作可能会引起数组容量的变化,导致数组越界等问题。...

  • 87-删除数组元素注意点

    需求: 遍历数组的同时删除数组中所有的元素通过传统遍历数组的方式弊端: 删除不尽元素 let arr = [...

  • 遍历数组的同时删除元素引起崩溃的问题以及解决方案

    遍历数组的同时删除元素引起崩溃的问题 一、问题 使用 for in遍历可变数组的同时删除元素会造成崩溃 崩溃日志为...

  • 数组遍历的同时删除元素

    正序遍历 方式一, 使用 for in遍历可变数组的同时删除元素会造成崩溃: 方式二, 使用 enumerateO...

  • iOS 常用的数据处理

    1. iOS遍历数组的同时删除元素 NSMutableArray*array = [NSMutableArraya...

  • js 数组操作

    遍历删除元素: 遍历数组:for循环遍历: forEach遍历:

  • ios数组

    //枚举遍历和for循环遍历可以在遍历的同时删除里面的元素,但用for in会出现数组越界异常,要想用for in...

  • iOS遍历数组的同时删除元素

    我们在遍历可变数组时,最好不要做删除数组中元素的操作。因为删除操作可能会引起数组容量的变化,导致数组越界等问题。以...

  • Swift 4.0 数组(Array)学习

    定义数组常量(常量只有读操作) 定义数组变量 赋值 取值 删除元素 添加元素 元素重新赋值 数组遍历

  • Swift学习之数组、集合和字典

    [toc] 数组 初始化一个数组 增加数组元素 读取数组元素 修改数组元素 删除数组元素 数组遍历 集合 集合类型...

网友评论

      本文标题:数组遍历自身的同时删除元素

      本文链接:https://www.haomeiwen.com/subject/leurqxtx.html