我有两个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多名在线用户将花费更多时间。有更快的解决方案吗?
感谢。
答案 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
必须经历一个对象列表,一次一个,要求他们计算他们的哈希值,然后将它们插入到桶中,这需要至少一些动态分配。
因此,如果可能的话,每次运行此测试时都不要重新创建nsset1
和nsset2
。在运行时将它们保存为集合,即使这意味着进出数组以存储到磁盘。
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 是: