2013-02-13 33 views
5

我有一个NSMutableArray,它具有实体类对象作为其对象。 现在我想从中删除不同的对象。考虑下面的例子在iPhone中使用NSPredicate从NSMutableArray获取不同的实体对象sdk

Entity *entity = [[Entity alloc] init]; 
entity.iUserId = 1; 
entity.iUserName = @"Giri" 
[arr addObject:entity]; 

Entity *entity = [[Entity alloc] init]; 
entity.iUserId = 2; 
entity.iUserName = @"Sunil" 
[arr addObject:entity]; 

Entity *entity = [[Entity alloc] init]; 
entity.iUserId = 3; 
entity.iUserName = @"Giri" 
[arr addObject:entity]; 

现在,我通过删除重复的iUserName想在Array只有两个对象。我通过迭代知道方式,但是我希望它不会像predicate或其他方式那样迭代它。 如果有人知道,那么请帮助我。 我曾尝试过使用[arr valueForKeyPath:@"distinctUnionOfObjects.iUsername"];,但它并没有将我退休的对象返回给我。

此问题与先前提出的问题完全不同。以前问的问题是为了获得不同的对象是正确的,但他们使用循环&我不想这样。我想从NSPredicate或其他避免循环的简单选项中获得。

+0

“in iphone sdk” - 谢谢!自从有人正确使用它(而不是使用不恰当的“使用Xcode”术语)已经很长时间了。 – 2013-02-13 13:23:55

+0

我记得我已经解决了这样的问题3-4次。所以不要害羞搜索/谷歌。 – 2013-02-13 13:28:18

+1

@AKV我想通过比较实体类对象中的实体来区分不同的元素。另外我想避免for循环。是否有可能通过谓词或任何其他选项 – Girish 2013-02-13 13:32:20

回答

0

那么你有几个选择(我可以想到)。

  1. 使用NSSet而不是NSArray。
  2. 使用for循环(但不想遍历数组)
  3. 使用谓词搜索iUserName可以在将名称添加到数组之前查看该名称是否存在。

喜欢的东西:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"iUserName == 'Giri'"]; 
NSArray *searchArray = [arr filterUsingPredicate:predicate]; 
4

编辑:你不能做你想要什么,而无需手动循环阵列上,并建立一个新的数组。下面的答案将不起作用,因为它假定最多只有两个副本。

NSMutableArray *filteredArray = [NSMutableArray array]; 

for (Entity *entity in arr) 
{ 
    BOOL hasDuplicate = [[filteredArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"iUserName == %@", entity.iUserName]] count] > 0; 

    if (!hasDuplicate) 
    { 
     [filteredArray addObject:entity]; 
    } 
} 

这将在它构建它时查找过滤数组中的重复项。

开始原来的答案

不能使用NSSet因为Entity情况下,将不得不在compareTo:返回NSOrderedSame,这不是一个好主意,因为你不应该使用的名称作为唯一标识符。

您可以使用谓词,但它们仍然会在O(n^2)时间内循环遍历数组,而无需进行一些优化。

NSArray *filteredArray = [arr filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(Entity *evaluatedObject, NSDictionary *bindings) { 
    return [[arr filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"iUserName == %@", evaluatedObject.iUserName]] count] > 1; 
}]]; 

这将工作正常。您可以通过首先对iUserName属性排序数组,并对排序后的数组执行线性扫描(当您看到第一个重复项时停止),使速度更快。如果您处理的是小样本量(例如,在一万个左右),那么这是很多工作。这可能不值得你花时间,所以只需使用上面的代码即可。

+0

我曾尝试过您的解决方案,但它不起作用。我使用了下面的代码:NSArray * filteredArray = [arr filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^ BOOL(Entity * entity,NSDictionary * bindings) {return [[arr filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@“iUsername ==%@”,exercise .iUsername]] count]> 1; }]]; – Girish 2013-02-13 14:41:06

+0

这应该工作,是的。 – 2013-02-13 14:42:38

+0

我的数组包含14个元素,其中7个是常见的,因此它需要返回6个元素,但它返回13个元素。 – Girish 2013-02-13 14:47:49

相关问题