【问题标题】:How to remove all dictionaries from NSMutableArray based on the value in the dictionary如何根据字典中的值从 NSMutableArray 中删除所有字典
【发布时间】:2014-07-04 07:38:30
【问题描述】:

我正在开发一个 iPad 应用程序。我有一个 NSMutableArrayNSMutableDictionary 。这两个都可以根据来自 Web 服务的数据进行更改。我需要根据 @987654324 从我的 NSMutableArray 中删除一些字典@ 值。这里我通过一个例子来说明情况:

testArray =[{ language :"ESP"},{language :"ENG"},{language :"ENG"},{language :"FRH"}];

我需要从测试数组中删除所有具有键值语言的字典:“ENG”。

我写过这样的代码:

 for(int i =0;i<testArray.count;i++){
    NSString *lang  = [NSString stringWithFormat:@"%@", [testArray[i] objectForKey:@"language"]];
    if([lang isEqualToString:@"ENG"]){
       [testArray removeObjectAtIndex:i];
       }
 }

但它不起作用。我认为问题是当我从索引处删除字典时,数组计数也在减少,因此循环是根据新数组计数执行的。一些帮助我重写代码以获得确切答案?

【问题讨论】:

  • 具体是什么不起作用?您是遇到异常还是只是您没有遍历所有值?
  • 您在 NSLog 中得到的输出不是预期的

标签: ios objective-c


【解决方案1】:

这是我最喜欢的方式,快速、清晰、正确。

NSMutableArray *itemsToRemove = [NSMutableArray array];
for (id item in theArray) {
    if ([item shouldBeRemoved])// Condition to check the key pair Value
        [itemsToRemove addObject:item];
}
[theArray removeObjectsInArray:itemsToRemove];

【讨论】:

  • 老实说,您的方法确实。您正在进行线性搜索 2 次。第一次提取要删除的项目,然后第二次迭代以实际删除找到的元素。我刚刚比较了性能:6.03 秒与 0.13 秒(使用 NSPredicate)。
【解决方案2】:

试试这个。

NSMutableArray *arrTemp = [[NSMutableArray alloc]initwithArray:testArray];
for(int i =0;i<testArray.count;i++){
    NSString *lang  = [NSString stringWithFormat:@"%@", [testArray[i] objectForKey:@"language"]];
    if([lang isEqualToString:@"ENG"]){
       [arrTemp removeObjectAtIndex:i];
   }
 }
[testArray removeAllObjects];
testArray = arrTemp;

【讨论】:

    【解决方案3】:
    for(int i =0;i<testArray.count;i++){
         NSString *lang  = [NSString stringWithFormat:@"%@", [testArray[i] objectForKey:@"language"]];
        if([lang isEqualToString:@"ENG"]){
           [testArray removeObjectAtIndex:i];
           i--;
         }
     }
    

    【讨论】:

      【解决方案4】:

      用下面的代码替换你的代码。

      NSMutableArray *arrTemp = [NSMutableArray new];
      for(int i =0;i<testArray.count;i++){
          NSString *lang  = [NSString stringWithFormat:@"%@", [testArray[i] objectForKey:@"language"]];
          if([lang isEqualToString:@"ENG"]){
      
              [arrTemp addObject:[NSNumber numberWithInt:i]];
          }
      }
      
      for(int k=0;k<[arrTemp count];k++)
      {
          int ii = [[arrTemp objectAtIndex:k]intValue];
          [testArray removeObjectAtIndex:ii];
      }
      

      让我知道它是否有效!!!

      编码愉快!!!

      【讨论】:

        【解决方案5】:

        我会使用NSPredicate

        NSMutableArray *testArray = [@[@{ @"language" :@"ESP"}, @{@"language" :@"ENG"},
        @{@"language" :@"ENG"}, @{@"language" :@"FRH"}] mutableCopy];
        NSPredicate *predicate = 
        [NSPredicate predicateWithFormat:@"language != %@", @"ENG" ];
        testArray = [[testArray filteredArrayUsingPredicate:predicate] mutableCopy];
        

        我刚刚测试过它,它可以工作(它很短而且很好读,但是NSPredicate 可能真的很慢)。

        另一种方法是使用enumerateObjectsWithOptions:usingBlock

        [testArray enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSDictionary *dict, NSUInteger index, BOOL *stop) {
            if ([dict[@"language"] isEqualToString:@"ENG"]) {
                [testArray removeObjectAtIndex:index];
            }
        }];
        

        请注意,我使用NSEnumerationReverse 作为NSEnumerationOptions,因为根据removeObjectAtIndex:docs- 方法:

        为了填补空白,所有超出索引的元素都通过减 1 移动 来自他们的索引。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-02-16
          • 2020-10-20
          • 1970-01-01
          • 1970-01-01
          • 2020-10-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多