Digamos que tengo una matriz con objetos, 1, 2, 3 y 4. ¿Cómo elegiría un objeto aleatorio de esta matriz?Escogiendo un objeto aleatorio en un NSArray
Respuesta
@ respuesta de Darryl es correcta, pero podría utilizar algunos ajustes menores:
NSUInteger randomIndex = arc4random() % [theArray count];
Modificaciones:
- Uso
arc4random()
sobrerand()
yrandom()
es más sencillo, ya que no requiere de la siembra (llamandosrand()
osrandom()
). - modulo operator (
%
) hace que la declaración general sea más corta, a la vez que la hace semánticamente más clara. theArray.count
es incorrecto. Funcionará, perocount
no está declarado como@property
enNSArray
, y por lo tanto no se invocará a través de la sintaxis de puntos. Que funcione es simplemente un efecto secundario de cómo el compilador interpreta la sintaxis de punto.
Tenga en cuenta que RC4/ARC4 no da salida uniforme. –
"theArray.count está equivocado. Funcionará, pero el recuento no se declara como @property en NSArray y, por lo tanto, no se debe invocar mediante la sintaxis de punto". --- Esto no es correcto La sintaxis de puntos y las propiedades declaradas no están realmente relacionadas: puede usar la sintaxis de puntos en métodos sin argumentos sin ningún problema. –
Desde la página de manual de arc4random: se recomienda arc4random_uniform() sobre construcciones como '' arc4random()% upper_bound '' ya que evita el "sesgo de módulo" cuando el límite superior no es una potencia de dos. –
Genere un número aleatorio y úselo como índice. Ejemplo:
#import <Foundation/Foundation.h>
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;
}
¡Tan simple y sin embargo funciona tan bien! – Joshua
@Joshua si quiere un poco más de detalle, puede usar 'SecRandomCopyBytes()' para obtener números aleatorios criptográficamente útiles, de todos modos en el iPhone. En Mac, tienes acceso directo a/dev/random. –
Un número aleatorio debería ser suficiente, pero gracias de todos modos por la información adicional. – Joshua
Tal vez algo en la línea de:
NSUInteger randomIndex = (NSUInteger)floor(random()/RAND_MAX * [theArray count]);
No se olvide de inicializar el generador de números aleatorios (srandomdev(), por ejemplo).
NOTA: He actualizado para usar -count en lugar de sintaxis punto, por la respuesta a continuación.
srand([[NSDate date] timeIntervalSince1970]);
int inx =rand()%[array count];
inx es el número aleatorio.
donde srand() puede estar en cualquier lugar del programa antes de la función de selección aleatoria.
Esta es la solución más simple que podía llegar a:
id object = array.count == 0 ? nil : array[arc4random_uniform(array.count)];
Es necesario comprobar count
debido a un no nil
pero vacío NSArray
regresará 0
para count
y arc4random_uniform(0)
vuelve 0
. Entonces sin el cheque, saldrás de límites en la matriz.
Esta solución es tentador, pero es mal porque va a causar un accidente con una matriz vacía:
id object = array[arc4random_uniform(array.count)];
Como referencia, aquí está la documentation:
páginau_int32_t
arc4random_uniform(u_int32_t upper_bound);
arc4random_uniform() will return a uniformly distributed random number less than upper_bound.
El hombre doesn' Mencione que arc4random_uniform
devuelve 0
cuando 0
se pasa como upper_bound
.
También, arc4random_uniform
se define en <stdlib.h>
, pero no fue necesario agregar el #import
en mi programa de prueba de iOS.
@interface NSArray<ObjectType> (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: Actualización de Xcode 7. Los medicamentos genéricos, nulabilidad
ObjectType *objectVarName = [array objectAtIndex:arc4random_uniform((int)(array.count - 1))];
si quieres lanzar que a un int, aquí está la solución para eso (útil para cuando se necesita un int azar de una matriz de números no secuenciales, en el caso de la aleatorización de una llamada enum, etc)
int intVarName = (int)[(NSNumber *)[array objectAtIndex:arc4random_uniform((int)(array.count - 1))] integerValue];
en Swift 4:
let array = ["one","two","three","four"]
let randomNumber = arc4random_uniform(UInt32(array.count))
array[Int(randomNumber)]
Revise [Cómo escribo una buena respuesta] (https://stackoverflow.com/help/how-to-answer). Las respuestas de solo código se desalientan porque no explican cómo resuelven el problema en la pregunta. Debe actualizar su respuesta para explicar lo que hace y cómo mejora en las muchas respuestas que esta pregunta de 7 años ya tiene – FluffyKitten
- 1. Escogiendo un elemento aleatorio de un conjunto
- 2. Escogiendo un framework ColdFusion MVC
- 3. Reorganizar NSArray/MSMutableArray en orden aleatorio
- 4. ¿Cómo encontrar un objeto de cierto tipo en un NSArray?
- 5. ¿NSArray: lastObject devuelve un objeto liberado automáticamente?
- 6. Obtener un NSArray de un solo atributo de un NSArray
- 7. Compruebe si un objeto es un NSArray o NSDictionary
- 8. Python: Escogiendo un elemento sin reemplazo
- 9. Escoja elemento aleatorio de NSArray en Objective-C
- 10. objeto NSArray multidimensional
- 11. Cómo usar NSArray del objeto NSArray en el objetivo c?
- 12. Objeto en el índice en NSArray
- 13. ¿Qué le sucede a un objeto NSArray cuando se codifica?
- 14. Simple: objeto NSArray a Doble?
- 15. Inserte NSArray en un NSDictionary
- 16. Cómo almacenar un NSArray en un NSDictionary?
- 17. Obteniendo el índice de un objeto de NSArray?
- 18. Tamaño de un NSArray
- 19. ¿Cómo extiendo un NSArray?
- 20. Guardar un NSArray
- 21. ¿Enumeras la tienda en un NSArray?
- 22. elemento aleatorio en un mapa
- 23. Número aleatorio en un bucle
- 24. Escogiendo el idioma correcto
- 25. ¿Cómo comprobar si un NSArray contiene un objeto de una clase en particular?
- 26. ¿Cómo obtengo el índice de un objeto en un NSArray usando el valor de cadena?
- 27. La búsqueda de un índice de objeto en NSArray usando un bloque de línea
- 28. Objeto aleatorio no desechable en C#
- 29. clasificar un NSArray de NSDates
- 30. Creación de un NSArray vacío
Todas las respuestas aquí son correctas, pero para obtener una solución más actualizada, consulte mi respuesta [aquí] (http://stackoverflow.com/a/10837462/730701). Utiliza el método 'arc4random_uniform' para evitar el sesgo de módulo. – Adam