我正在尝试制作应用程序,需要从CoreData中获取N个随机对象。Swift + CoreData。从数据库中获取N个随机对象。 N << size(DB)
问题是数据库的大小远远大于我想要获取的对象的数量。因此,最好有一种方法不会影响数据库中的所有记录。
是否可以在不向数据库添加额外字段的情况下实现这一点(例如,id)?
我想要接收不同的请求响应,所以选项“预先使用一些随机函数排序”不起作用。
我正在尝试制作应用程序,需要从CoreData中获取N个随机对象。Swift + CoreData。从数据库中获取N个随机对象。 N << size(DB)
问题是数据库的大小远远大于我想要获取的对象的数量。因此,最好有一种方法不会影响数据库中的所有记录。
是否可以在不向数据库添加额外字段的情况下实现这一点(例如,id)?
我想要接收不同的请求响应,所以选项“预先使用一些随机函数排序”不起作用。
一个接一个取物体的问题可能是性能问题。取决于n
的大小,这可能不会缩放。
相反,您可以利用Core Data在处理大量对象时非常高效的事实。由于称为“错误”的机制,您可以获取数以万计的对象而不会有太大的内存占用。
因此,我建议您获取所有对象,并从结果中挑选出一些。
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Response"];
NSArray *all = [managedObjectContext executeFetchRequest:request error:nil];
NSMutableArray *pickedAnswers = [NSMutableArray array];
int remaining = 10;
if (all.count < remaining) { /* abort */ }
while (remaining > 0) {
Response *response = all[arc4random_uniform(all.count)];
if (![pickedAnswers containsObject:response]) {
[pickedAnswers addObject:response];
remaining--;
}
}
注意,另一个优雅的答案将是第一洗牌阵列(如所示here然后挑选第一n
元件)。这将消除通过while
循环的不必要的运行。
计数的所有记录第一:
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"<your entity name>"];
NSUInteger count = [context countForFetchRequest:request error:NULL];
使用fetchOffset
:
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"<your entity name>"];
request.fetchLimit = 1;
request.fetchOffset = arc4random_uniform(count);
NSArray *result = [context executeFetchRequest:request error:NULL];
重复N次,从而获得所需的对象的数量。