按键从NSMutableArray中删除对象

时间:2014-12-30 02:14:31

标签: ios nsmutablearray nsdictionary

NSMutableArray *array = [NSMutableArray arrayWithObjects:@{@"name":@"Jenny",@"age":@23},@{@"name":@"Daisy",@"age":@27},nil];

是否可以在数组的字典对象中按键删除对象?

例如。按年龄= 27删除对象

4 个答案:

答案 0 :(得分:8)

要从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}

答案 1 :(得分:4)

您可以使用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 );

答案 2 :(得分: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功能进行并排性能测试。迭代1000个字典的数组,从每个数组中删除一个与整数值匹配的项,并比较该项非常接近数组的开头,数组的中间和数组的末尾,两个版本倾向于在另一个的第二个千分之一内完成,其中谓词过滤器在每种情况下都非常快。 (我们正在谈论.269秒vs .261秒)

考虑到这一点,我认为在任何主要意义上, 我认为filteredArrayUsingPredicate方法虽然更干净。对于任何好奇的人来说,只是为思想添加一些额外的食物,并且让我有理由自己尝试使用measureBlock功能。 :)

答案 3 :(得分:1)

在这种情况下,您必须遍历每个项目并针对每个对象进行手动测试,这可能会很好,具体取决于您正在处理的数据大小和用例的复杂性。

或者,考虑将数据存储在sqlite数据库中,如果它对您有用,请查询它。