11

いくつかのランダムなインスタンスをフェッチしたい管理対象オブジェクトの大規模なコレクションがあるアプリで作業しています。

私の質問は、NSPredicateとNSFetchRequestを使用して複数のオブジェクトをランダムに返す方法はありますか?

データモデラーを使用してエンティティにNSFetchRequestを実際に追加できることを確認しました。これを使用してランダムフェッチを実行する方法はありますか?

また、乱数ジェネレーターの境界を設定できるように、テーブルの「カウント」を決定するための最良の方法は何でしょうか。

詳細が必要な場合はお知らせください。

ありがとう!

ニック

4

5 に答える 5

20

代わりに、fetchLimit を fetchOffset と組み合わせて使用​​すると、単一のエンティティのみを効率的にメモリにフェッチできます。

NSFetchRequest *myRequest = [[NSFetchRequest alloc] init];
[myRequest setEntity: [NSEntityDescription entityForName:myEntityName inManagedObjectContext:myManagedObjectContext]];
NSError *error = nil;
NSUInteger myEntityCount = [myManagedObjectContext countForFetchRequest:myRequest error:&error];    

NSUInteger offset = myEntityCount - (arc4random() % myEntityCount);
[myRequest setFetchOffset:offset];
[myRequest setFetchLimit:1];

NSArray* objects = [myManagedObjectContext executeFetchRequest:myRequest error:&error];    
id randomObject = [objects objectAtIndex:0];
于 2011-03-06T04:09:50.260 に答える
5

これは、これを実装する方法とは正確に一致しない場合がありますが、うまくいけば、開始することができます。

ヘッダーまたは実装ファイルの上部のどこかにあります。

#import <stdlib.h>
#import <time.h>

実装の他の場所:

//
// get count of entities
//
NSFetchRequest *myRequest = [[NSFetchRequest alloc] init];
[myRequest setEntity: [NSEntityDescription entityForName:myEntityName inManagedObjectContext:myManagedObjectContext]];
NSError *error = nil;
NSUInteger myEntityCount = [myManagedObjectContext countForFetchRequest:myRequest error:&error];    
[myRequest release];

//
// add another fetch request that fetches all entities for myEntityName -- you fill in the details
// if you don't trigger faults or access properties this should not be too expensive
//
NSArray *myEntities = [...];

//
// sample with replacement, i.e. you may get duplicates
//
srandom(time(NULL)); // seed random number generator, so that you get a reasonably different series of random integers on each execution
NSUInteger numberOfRandomSamples = ...;
NSMutableSet *sampledEntities = [NSMutableSet setWithCapacity:numberOfRandomSamples];
for (NSInteger sampleIndex = 0; sampleIndex < numberOfRandomSamples; sampleIndex++) {
    int randomEntityIndex = random() % myEntityCount; // generates random integer between 0 and myEntityCount-1
    [sampledEntities addObject:[myEntities objectAtIndex:randomEntityIndex]];
}

// do stuff with sampledEntities set

置換せずにサンプリングする必要がある場合は、重複を排除するために、ランダムなをサンプリングするだけでなく、オブジェクトNSSetのを作成することができます。randomEntityIndex NSNumberint

この場合、注文したオブジェクトからサンプリングし、バッグからオブジェクトを引き出すときにオブジェクトをNSSet削除し、セットからランダムなオブジェクトを選択するためにデクリメントします。NSNumbermyEntityCountNSNumber

于 2010-05-13T22:17:08.740 に答える
0

とにかくすべてのオブジェクトをフェッチする場合、最初のリクエストでオブジェクト数を取得する必要はありません。次のようなものを使用できます。

myEntityCount = [myEntities count]
于 2010-12-14T00:18:51.333 に答える