ios - 从其他NSSet中减去NSSet

时间:2015-01-19 13:29:51

标签: ios nspredicate nsset

我有两个NSSet个。一个包含所有UserKeys,另一个包含在线用户密钥。我想在这两个部分中显示这些值。第1节 - 在线用户和第2节 - 其他用户

我使用下面的谓词做了这个。

NSSet *nsset1 = [NSSet setWithArray:attendeesService.arrof_attendeeList]; //this are all users
nsset2 = [NSSet setWithArray:tempArray]; // temparray contains all online users.
NSSet *nsset2_ids = [nsset2 valueForKey:@"UserProfileKEY"]; 
nsset1_minus_nsset2 = [nsset1 filteredSetUsingPredicate:[NSPredicate predicateWithFormat:@"NOT UserProfileKEY IN %@",nsset2_ids]]; 

工作正常。但是所有用户大约3000+,在线可能一次超过200+。所以需要花费很多时间。 4-5名在线用户需要1分钟。因此,200多名在线用户将花费更多时间。有更快的解决方案吗?

感谢。

3 个答案:

答案 0 :(得分:9)

使用minusSet

中的NSMutableSet

minusSet: 从接收集中移除另一个给定集合中的每个对象(如果存在)。

NSMutableSet *nsset1 = [NSMutableSet setWithArray: attendeesService.arrof_attendeeList];
NSSet *set2 = [NSSet setWithArray: tempArray];
[nsset1 minusSet: set2];
NSArray *nsset1_minus_nsset2 = [nsset1 allObjects];

答案 1 :(得分:1)

集合创建很昂贵 - NSSet必须经历一个对象列表,一次一个,要求他们计算他们的哈希值,然后将它们插入到桶中,这需要至少一些动态分配。

因此,如果可能的话,每次运行此测试时都不要重新创建nsset1nsset2。在运行时将它们保存为集合,即使这意味着进出数组以存储到磁盘。

集合上的

valueForKey:也是集创建任务。尽量不这样做。至少切换到nsset2_ids = [NSSet setWithArray:[tempArray valueForKey:@"UserProfileKEY"]];只创建一个而不是两个。

根据gabbler在minusSet上使用NSMutableSet,以防止解析和应用自由形式谓词的成本。

如果可能,这两个集合包含相同类型的对象并正确实施isEqual:hash,以便不需要转换(您通过valueForKey:实现的转换)首先。

答案 2 :(得分:1)

您的第一个数组是FirstMakes声明:

NSArray *FirstMakes = @[@"Mercedes-Benz", @"BMW", @"Porsche",
                         @"Opel", @"Volkswagen", @"Audi"];

您的第二个数组是SecondMakes声明:

NSArray *SecondMakes = @[@"Mercedes-Benz", @"Porsche",
                          @"Volkswagen"];

Filter `FirstMakes` to `SecondMakes`

NSPredicate *beforeL = [NSPredicate predicateWithBlock:
                            ^BOOL(id evaluatedObject, NSDictionary *bindings)
                             {

                                 if ([SecondMakes containsObject:evaluatedObject])
                                 {
                                     return NO;
                                 }
                                 else{
                                     return YES;
                                 }

                            }];
    NSArray *makesBeforeL = [FirstMakes
                             filteredArrayUsingPredicate:beforeL];

    NSLog(@"%@", makesBeforeL);

OUTPUT 是:

enter image description here