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
必须遍历对象列表,一次一个,要求它们计算它们的哈希值,然后将它们插入桶中,这至少需要一些动态分配。
因此,如果可能,请不要在每次 运行 此测试时重新创建 nsset1
和 nsset2
。在 运行 时将它们保持为集合,即使这意味着要往返于阵列以存储到磁盘。
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);
您的输出是:
我有两个 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
必须遍历对象列表,一次一个,要求它们计算它们的哈希值,然后将它们插入桶中,这至少需要一些动态分配。
因此,如果可能,请不要在每次 运行 此测试时重新创建 nsset1
和 nsset2
。在 运行 时将它们保持为集合,即使这意味着要往返于阵列以存储到磁盘。
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);
您的输出是: