我正在嘗試製作應用程序,需要從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次,從而獲得所需的對象的數量。