按键从 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 中删除对象?

如何从 NSMutableArray 中删除 nil 对象?

我怎样才能从NSMutableArray中删除[NSNull Null]对象?

从 NSMutableArray 中删除 for 循环中的对象

从 NSMutableArray xcode 中删除对象

从 NSMutableArray 中删除重复的自定义对象,确保保留最新的重复对象