Скажімо, у мене є масив із об’єктами, 1, 2, 3 та 4. Як вибрати випадковий об’єкт із цього масиву?
Скажімо, у мене є масив із об’єктами, 1, 2, 3 та 4. Як вибрати випадковий об’єкт із цього масиву?
Відповіді:
Відповідь @ Дарріла правильна, але міг би використати деякі незначні налаштування:
NSUInteger randomIndex = arc4random() % theArray.count;
Модифікації:
arc4random()over rand()і random()простіше, оскільки не вимагає засівання (дзвінка srand()або srandom()).%) робить загальний вираз коротшим, а також робить його семантично чіткішим.0 % 4 = 0, 1 % 4 = 1, 2 % 4 = 2, 3 % 4 = 3, 4 % 4 = 0, 5 % 4 = 1... Якщо ви по модулю по п , ваш найбільший результат ніколи не буде більше , ніж п-1 .
countє властивістю:@interface NSArray<__covariant ObjectType> : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration> @property (readonly) NSUInteger count;
Це найпростіше рішення, яке я міг придумати:
id object = array.count == 0 ? nil : array[arc4random_uniform(array.count)];
Необхідно перевірити , countтак як не- nilале спустошити NSArrayповернеться 0до count, і arc4random_uniform(0)повертається 0. Тож без перевірки ви вийдете за межі масиву.
Це рішення спокусливе, але неправильне, оскільки спричинить збій з порожнім масивом:
id object = array[arc4random_uniform(array.count)];
Для довідки, ось документація :
u_int32_t
arc4random_uniform(u_int32_t upper_bound);
arc4random_uniform() will return a uniformly distributed random number less than upper_bound.
Сторінка не згадує, що arc4random_uniformповертається, 0коли 0передається як upper_bound.
Крім того, arc4random_uniformце визначено в <stdlib.h>, але додавання #importнеобов’язкового в моїй тестовій програмі iOS.
Можливо, щось на зразок:
NSUInteger randomIndex = (NSUInteger)floor(random()/RAND_MAX * [theArray count]);
Не забудьте ініціалізувати генератор випадкових чисел (наприклад, srandomdev ()).
ПРИМІТКА. Відповідно до наведеної нижче відповіді я оновив для використання -count замість синтаксису крапок.
@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
Редагувати: оновлено для Xcode 7. Загальні засоби, що дозволяють онулювати
Створіть випадкове число і використовуйте його як індекс. Приклад:
#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;
}
SecRandomCopyBytes()для отримання криптографічно корисних випадкових чисел на iPhone у будь-якому випадку. На Mac ви маєте прямий доступ до / dev / random.
srand([[NSDate date] timeIntervalSince1970]);
int inx =rand()%[array count];
inx - випадкове число.
де srand () може бути де завгодно в програмі до функції випадкового вибору.
ObjectType *objectVarName = [array objectAtIndex:arc4random_uniform((int)(array.count - 1))];
якщо ви хочете передати це на int, ось рішення для цього (корисно, коли вам потрібен випадковий int з масиву непослідовних чисел, у випадку рандомізації виклику перерахування тощо)
int intVarName = (int)[(NSNumber *)[array objectAtIndex:arc4random_uniform((int)(array.count - 1))] integerValue];
У Swift 4:
let array = ["one","two","three","four"]
let randomNumber = arc4random_uniform(UInt32(array.count))
array[Int(randomNumber)]
arc4random_uniformметод, щоб уникнути зміщення за модулем.