按键从 NSMutableArray 中删除对象
Posted
技术标签:
【中文标题】按键从 NSMutableArray 中删除对象【英文标题】:remove object from NSMutableArray by key 【发布时间】:2014-12-30 02:14:31 【问题描述】:NSMutableArray *array = [NSMutableArray arrayWithObjects:@@"name":@"Jenny",@"age":@23,@@"name":@"Daisy",@"age":@27,nil];
是否可以在数组的字典对象中按键删除对象?
例如。按年龄删除对象 = 27
【问题讨论】:
你的意思是要删除第二本词典? 【参考方案1】:要从 NSArray 中过滤对象,请调用 filteredArrayUsingPredicate
:
NSArray *array = @[@@"name":@"Jenny",@"age":@23,@@"name":@"Daisy",@"age":@27];
NSArray *array2 =
[array filteredArrayUsingPredicate:
[NSPredicate predicateWithBlock:^BOOL(id obj, NSDictionary *d)
return ![[obj valueForKey:@"age"] isEqual:@27];
]];
现在array2
是所需的数组 - 它是第一个没有年龄为 27 岁的数组。
顺便说一句,我知道这不是你问的,但是这种事情是切换到 Swift 的一个很好的理由。它太简单了;这类问题就像 Swift 的一个活生生的霓虹灯技术广告:
let array = [["name":"Jenny", "age":23],["name":"Daisy", "age":27]]
let array2 = array.filter $0["age"] != 27
【讨论】:
非常有趣,之前从未在核心数据之外使用过谓词。这是否仍然在最坏的情况下执行 n 次迭代的搜索,还是比正常的迭代过程更有效? @Mike 这只是一个循环。【参考方案2】:您可以使用NSPredicate
创建一个缺少不需要的条目的新数组。 NSPredicate
类似于数据库查询,输入 NSArray 表示数据库,输出数组是查询的响应。
NSArray *array = @[ @@"name":@"Jenny",@"age":@23,
@@"name":@"Daisy",@"age":@27 ];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age != 27"];
NSArray *filtered = [array filteredArrayUsingPredicate:predicate];
NSLog( @"%@", array );
NSLog( @"%@", filtered );
【讨论】:
【参考方案3】:我不确定是否有更直接的方法,但一种方法是简单地遍历数组并测试值。您不能在枚举时改变数组,这意味着您不能在遍历它时删除一个对象,因此一种方法是获取与您的条件匹配的对象的索引,如果找到一个,打破并删除该项目那个索引。类似于以下内容:
NSInteger indexToDelete = -1;
for (NSInteger i = 0; i < array.count; i++)
NSDictionary *dict = array[i];
if ([dict[@"age"] integerValue] == 27)
indexToDelete = i;
break;
if (indexToDelete > 0)
[array removeObjectAtIndex:indexToDelete];
对使用 filteredArrayUsingPredicate
的其他答案很感兴趣,我对性能很好奇,并决定使用 Xcode 的 measureBlock
功能进行并行性能测试。遍历包含 1,000 个字典的数组,从每个数组中删除一个与整数值匹配的项目,并比较该项目何时非常接近数组的开头、数组的中间和数组的结尾,两个版本倾向于在另一个秒的几千分之内完成,谓词过滤器在每种情况下都稍微快一点。 (我们谈论的是 0.269 秒与 0.261 秒)
考虑到这一点,我认为在任何主要意义上都比另一个更好,它只是归结为偏好。我确实认为filteredArrayUsingPredicate 方法更干净。对于任何好奇的人来说,只是一些额外的思考,并让我有理由自己尝试 measureBlock 功能。 :)
【讨论】:
需要考虑的事情:如果输入数组有多个条目,其中age == 27
?
很好,如果是这种情况,并且您想删除所有这些,只需删除中断即可。【参考方案4】:
在这种情况下,您必须遍历每个项目并对每个对象进行手动测试,这可能会很好,具体取决于您处理的数据大小和用例的复杂性。
或者,考虑将数据存储在 sqlite 数据库中,并在对您可行的情况下对其进行查询。
【讨论】:
您只需要确保在枚举时不会发生变异。以上是关于按键从 NSMutableArray 中删除对象的主要内容,如果未能解决你的问题,请参考以下文章
如何从 NSMutableArray 中删除 nil 对象?
我怎样才能从NSMutableArray中删除[NSNull Null]对象?