Escolhendo um object random em um NSArray

Digamos que eu tenha uma matriz com objects, 1, 2, 3 e 4. Como eu escolheria um object random dessa matriz?

@ Resposta Darryl está correta, mas poderia usar alguns pequenos ajustes:

 NSUInteger randomIndex = arc4random() % theArray.count; 

Modificações:

  • Usar arc4random() sobre rand() e random() é mais simples porque não requer propagação (chamando srand() ou srandom() ).
  • O operador de módulo ( % ) torna a instrução geral mais curta, ao mesmo tempo em que a torna semanticamente mais clara.

Esta é a solução mais simples que eu poderia encontrar:

 id object = array.count == 0 ? nil : array[arc4random_uniform(array.count)]; 

É necessário checar a count porque um NSArray não nil mas vazio, retornará 0 para count , e arc4random_uniform(0) retornará 0 . Portanto, sem o cheque, você sairá dos limites da matriz.

Esta solução é tentadora, mas está errada porque causará uma falha com uma matriz vazia:

 id object = array[arc4random_uniform(array.count)]; 

Para referência, aqui está a documentação :

 u_int32_t arc4random_uniform(u_int32_t upper_bound); arc4random_uniform() will return a uniformly distributed random number less than upper_bound. 

A página man não menciona que arc4random_uniform retorna 0 quando 0 é passado como upper_bound .

Além disso, arc4random_uniform é definido em , mas não foi necessário adicionar o #import no meu programa de teste do iOS.

Talvez algo ao longo das linhas de:

 NSUInteger randomIndex = (NSUInteger)floor(random()/RAND_MAX * [theArray count]); 

Não esqueça de inicializar o gerador de números randoms (srandomdev (), por exemplo).

OBSERVAÇÃO: atualizei para usar a contagem em vez da syntax de pontos, conforme a resposta abaixo.

 @interface NSArray (Random) - (nullable ObjectType)randomObject; @end @implementation NSArray (Random) - (nullable id)randomObject { id randomObject = [self count] ? self[arc4random_uniform((u_int32_t)[self count])] : nil; return randomObject; } @end 

Editar: Atualizado para o Xcode 7. Genéricos, anulação

Gere um número random e use-o como o índice. Exemplo:

 #import  int main(int argc, const char * argv[]) { @autoreleasepool { NSArray *array = [NSArray arrayWithObjects: @"one", @"two", @"three", @"four", nil]; NSUInteger randomNumber; int fd = open("/dev/random", O_RDONLY); if (fd != -1) { read(fd, &randomNumber, sizeof(randomNumber)); close(fd); } else { fprintf(stderr, "Unable to open /dev/random: %s\n", strerror(errno)); return -1; } double scaledRandomNumber = ((double)randomNumber)/NSUIntegerMax * [array count]; NSUInteger randomIndex = (NSUInteger)floor(scaledRandomNumber); NSLog(@"random element: %@", [array objectAtIndex: randomIndex]); } return 0; } 
  srand([[NSDate date] timeIntervalSince1970]); int inx =rand()%[array count]; 

inx é o número random.

onde srand () pode estar em qualquer lugar no programa antes da function de seleção aleatória.

 ObjectType *objectVarName = [array objectAtIndex:arc4random_uniform((int)(array.count - 1))]; 

Se você quiser converter isso para um int, aqui está a solução para isso (útil para quando você precisa de um int random de uma matriz de números não seqüenciais, no caso de randomizar uma chamada enum, etc)

 int intVarName = (int)[(NSNumber *)[array objectAtIndex:arc4random_uniform((int)(array.count - 1))] integerValue]; 

No Swift 4:

 let array = ["one","two","three","four"] let randomNumber = arc4random_uniform(UInt32(array.count)) array[Int(randomNumber)]