Cómo aleatorizar contenido de celdas de una matriz

Tal como está, el siguiente código extrae datos de la matriz "cellArray" para formar una UICollectionView con 25 celdas. Quiero aleatorizar los datos que se utilizan sin repetir . A partir de ahora, solo hay 25 elementos de matriz. Más adelante, habrá más, pero solo quiero que aparezcan 25 celdas. Intenté insert "NSUInteger randomIndex = arc4random ()% [theArray count];" Sin embargo, no pude lograr que funcionara y, según mi entendimiento, esto tiene un sesgo de module.

También sería una ventaja si la célula 13 pudiera tener un text constante (no cambiante).

@implementation CollectionViewController //Delegate Methods -(NSInteger) numberOfSectionsInCollectionView:(UICollectionView *)collectionView { return 1; } -(NSInteger) collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return self.cellArray.count; } -(UICollectionViewCell*) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { Cell * aCell = [collectionView dequeueReusableCellWithReuseIdentifier:@"bingoCell1" forIndexPath:indexPath]; aCell.cellContent.text = self.cellArray[indexPath.row]; return aCell; } - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.cellArray = @[@"Type 1", @"Type 2", @"Type 3", @"Type 4", @"Type 5", @"Type 6", @"Type 7", @"Type 8", @"Type 9", @"Type 10", @"Type 11", @"Type 12", @"Free Space", @"Type 14", @"Type 15", @"Type 16", @"Type 17", @"Type 18", @"Type 19", @"Type 20", @"Type 21", @"Type 22", @"Type 23", @"Type 24", @"Type 25"]; } 

Realice un shuffle in self.cellArray en self.cellArray para aleatorizar su order sin repeticiones. Tomé el código aleatorio de esta pregunta , que debe colocarse en una categoría NSMutableArray:

 //CollectionViewController.m #import "NSMutableArray+Shuffle.h" - (void)viewDidLoad { [super viewDidLoad]; self.cellArray = @[@"Type 1", @"Type 2", @"Type 3", ...]; NSIndexSet *beforeThirteen = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 12)]; NSIndexSet *afterThirteen = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(13, self.cellArray.count-13)]; //Build an array with all objects except for the thirteenth one NSMutableArray *arrayWithoutThirteenthObject = [NSMutableArray array]; [arrayWithoutThirteenthObject addObjectsFromArray:[self.cellArray objectsAtIndexes:beforeThirteen]]; [arrayWithoutThirteenthObject addObjectsFromArray:[self.cellArray objectsAtIndexes:afterThirteen]]; //Shuffle it [arrayWithoutThirteenthObject shuffle]; //Add the thirteenth object into the shuffled array [arrayWithoutThirteenthObject insertObject:self.cellArray[12] atIndex:12]; //Assign the shuffled array to the table view array self.cellArray = arrayWithoutThirteenthObject; } 

Al final, lo que hago es mezclar la matriz sin el decimotercio object y luego volver a agregarlo en el decimotercio índice después de que la matriz haya sido barajada, por lo que al final se barajará por completo excepto para el object en el decimotercer índice, que tiene permaneció en el mismo lugar

Solo por el bien de la accesibilidad, aquí está el código para el shuffle:

 //NSMutableArray+Shuffle.h @interface NSMutableArray (Shuffling) - (void)shuffle; @end //NSMutableArray+Shuffle.m @implementation NSMutableArray (Shuffling) - (void)shuffle { NSUInteger count = [self count]; for (NSUInteger i = 0; i < count; ++i) { NSInteger nElements = count - i; NSInteger n = (arc4random() % nElements) + i; [self exchangeObjectAtIndex:i withObjectAtIndex:n]; } } @end 

Los sets no están orderados y no pueden contener duplicates, por lo que son (casi) la solución perfecta para su problema. Comencemos creando un set desde su matriz.

 NSSet *set = [NSSet setWithArray:self.cellArray]; 

Está bien, pero ¿cómo se puede get un object de este set desorderado que se corresponda con nuestra ruta de índice? Solo podemos get objects de un NSSet utilizando anyObject . Y eso podría darnos el mismo object dos veces. Solución: haga un set orderado.

 NSOrdenetworkingSet *ordenetworkingSet = [NSOrdenetworkingSet ordenetworkingSetWithSet:set]; 

Luego, podemos sacar una secuencia orderada pero desorderada de nuestro set.

 -(UICollectionViewCell*) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { Cell * aCell = [collectionView dequeueReusableCellWithReuseIdentifier:@"bingoCell1" forIndexPath:indexPath]; aCell.cellContent.text = ordenetworkingSet[indexPath.row]; return aCell; }