ios - 从其他 NSSet 中减去 NSSet

ios - Subtract NSSet from other NSSet

我有两个 NSSet。一个包含所有用户密钥,另一个包含在线用户密钥。我想分两部分展示这个值。第 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+在线用户会花费更多的时间。有没有更快的解决方案?

谢谢。

使用minusSet from NSMutableSet

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

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

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

因此,如果可能,请不要在每次 运行 此测试时重新创建 nsset1nsset2。在 运行 时将它们保持为集合,即使这意味着要往返于阵列以存储到磁盘。

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

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

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

您的第一个数组是 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);

您的输出是: