2011-06-09 115 views
40

我不知道如何去做这件事。我有一个NSMutableArray(addList),其中包含要添加到我的数据源NSMutableArray的所有项目。NSMutableArray检查对象是否已经存在

我现在想检查从addList数组添加的对象是否已经存在于数据源数组中。如果不存在,则添加该项目,如果存在则忽略。

这两个对象都有一个名为iName的字符串变量,我想比较。

这里是我的代码片段

-(void)doneClicked{ 
    for (Item *item in addList){ 
     /* 
     Here i want to loop through the datasource array 
     */ 
     for(Item *existingItem in appDelegate.list){ 
      if([existingItem.iName isEqualToString:item.iName]){ 
       // Do not add 
      } 
      else{ 
       [appDelegate insertItem:item]; 
      } 
     } 
} 

,但我觉得,即使存在要添加的项目。

我在做什么错了?

+0

这是一个逻辑错误,请参阅我的回答 – knuku 2011-06-09 11:04:02

回答

39

我找到了一个解决方案,可能不是最有效的全部,但ATLEAST工作

NSMutableArray *add=[[NSMutableArray alloc]init]; 

for (Item *item in addList){ 
     if ([appDelegate.list containsObject:item]) 
      {} 
     else 
      [add addObject:item]; 
} 

然后我迭代添加数组并插入项目。

5

你试过indexOfObject:

-(void)doneClicked{ 
    for (Item *item in addList){ 
     if([appDelegate.list indexOfObject:item] == NSNotFound){ 
      [appDelegate insertItem:item]; 
     } 
} 

UPDATE:你有一个合乎逻辑的错误,不误代码。假设第一个数组是['a','b','c'],第二个数组是['a','x','y','z']。当你通过第二个数组迭代'a'时,它不会在第一次迭代时向第二个数组添加'a'(比较'a'和'a'),但会在第二个数组中添加(比较'a'和'x “)。这就是为什么你应该在你的'Item'对象中实现isEqual:方法(见下文)并使用上面的代码。

- (BOOL)isEqual:(id)anObject { 
    if ([anObject isKindOfClass:[Item class]]) 
     return ([self.iName isEqualToString:((Item *)anObject).iName]); 
    else 
     return NO; 
} 
+0

@ NR4TR:我想单独比较名称。不是整个对象 – Neelesh 2011-06-09 10:43:18

+0

检查出更新的答案 – knuku 2011-06-09 11:03:16

+0

是的,我现在得到它。但是,当我使用你已更新的代码,我得到以下错误 [项目isEqualToString:]:无法识别的选择器发送到实例0x712ee70 – Neelesh 2011-06-09 11:19:28

2

可以在物体上覆盖isEqualshash以便它返回一个YES/NO基于所述INAME属性的比较。

一旦你有,你可以使用...

- (void)removeObjectsInArray:(NSArray *)otherArray 

为了将所有剩余的对象之前清洗名单。

+0

首先,我想单独比较名称而不是整个对象 – Neelesh 2011-06-09 10:44:58

+1

考虑阅读有关'isEquals'方法的文档,它可以帮助 – knuku 2011-06-09 10:57:51

+1

是的,覆盖isEquals的想法是,您可以定义您认为的'通常情况下,运行时会查看两个对象,如果它们不是同一个实例,则返回false。通过重写isEquals方法,您可以说'实际上我不在乎对象是否不相同,在我眼中,这两个项目是相同的,如果名称匹配。' – 2011-06-09 10:58:09

1

转换小写和修剪空白,然后检查..

[string lowercaseString]; 

NSString *trim = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 
22

使用NSPredicate

NSArray *list = [[appDelegate.list copy] autorelease]; 

for (Item *item in addList) { 

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"iName MATCHES %@", item.iName]; 
    NSArray *filteredArray = [list filteredArrayUsingPredicate:predicate]; 
    if ([filteredArray count] > 0) [appDelegate insertItem:item]; 
} 
+1

+1不错的答案。避免了如果问题中使用的方法实际工作时会发生变异的收集异常。 – JeremyP 2011-06-09 11:20:57

+0

“list”数组的任何内存管理? :) – knuku 2011-06-09 11:23:09

+0

我尝试了上面编辑的解决方案。首先,程序崩溃而不显示任何错误。其次,即使它存在于数据源列表中,也会添加项目 – Neelesh 2011-06-09 11:27:29

2

NR4TR正确地说,但我认为一个突破声明足以


if([existingItem.iName isEqualToString:item.iName]){ 
       // Do not add 
break; 
      } 
+0

您可以粘贴该方法的整个代码。 – Neelesh 2011-06-09 11:46:18

4

看看NSSet。您可以添加对象,只有在对象是唯一的时才会添加对象。你可以从NSArray创建一个NSSet,反之亦然。

68

在NSArray中有一个非常有用的方法,即containsObject

NSArray *array; 
array = [NSArray arrayWithObjects: @"Nicola", @"Margherita",          @"Luciano", @"Silvia", nil]; 
if ([array containsObject: @"Nicola"]) // YES 
{ 
    // Do something 
} 
1

比较addList的第一个对象和appDelegate.list的第一个对象,如果它们不相等,则插入addList的对象。逻辑是错误的,你应该比较一个addList的对象与每个appDelegate.list的对象。

相关问题