如何随机化数组中的单元格内容

Posted

技术标签:

【中文标题】如何随机化数组中的单元格内容【英文标题】:How to randomize cell content from an array 【发布时间】:2013-10-13 05:28:45 【问题描述】:

就目前而言,以下代码从数组“cellArray”中提取数据以形成具有 25 个单元格的 UICollectionView。我想随机化正在使用的数据不重复。截至目前,只有 25 个数组元素。以后会有更多,但我只希望出现 25 个单元格。我尝试插入“NSUInteger randomIndex = arc4random() % [theArray count];”但是,我无法让它工作,据我了解,这有模偏差。

如果第 13 个单元格可以有恒定(不变)的文本,那也是一个好处。

@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"];


【问题讨论】:

【参考方案1】:

self.cellArray 上执行就地洗牌以随机化其顺序而不重复。我从this question 中获取了改组代码,它应该放在一个 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;

最后我所做的是在没有第十三个对象的情况下对数组进行洗牌,然后在数组洗牌后将其重新添加到第十三索引处,因此最后除了第十三索引处的对象外,它完全被洗牌,它一直在同一个地方。

为了便于访问,这里是随机播放的代码:

//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

【讨论】:

我假设我在创建 NSArray+Shuffle.h 和 NSArray+Shuffle.m 文件时使用子类“NSMutableArray”? 已编辑以上评论 @RileyLloyd - 它不完全是一个子类;它被称为一个类别。它们是向现有类添加方法的一种方式。你必须进入Xcode,当你点击“New File”时,应该有一个选择“Category”的选项。它将提示您输入类别的名称;称之为“随机播放”。 我还需要声明更多属性吗?当我运行它并单击按钮转到 UICollectionViewController 时,我会被发送到调试器。 没关系,重新复制并粘贴你的代码,效果很好,除了我现在缺少第 25 个单元格(类型 25),总共只有 24 个,包括第 13 个。【参考方案2】:

集合是无序的,不能包含重复项,因此它们(几乎)是解决您问题的完美方案。让我们从您的数组创建一个集合开始。

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

好的,但是如何从这个无序集合中获取一个与我们的索引路径对应的对象呢?我们只能使用anyObject 从 NSSet 中获取对象。这可以给我们两次相同的对象。解决方案 - 创建一个有序集合。

NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithSet:set];

然后我们可以从我们的集合中拉出一个无序但有序的字符串。

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

【讨论】:

以上是关于如何随机化数组中的单元格内容的主要内容,如果未能解决你的问题,请参考以下文章

EXCEL中,如何引用一个单元格中的数据,作为另一个单元格内容中的一部分?

Excel单元格内容包含指定单元格内容时,如何把“指定单元格2”复制到“单元格1”后面?

DataGridView控件中如何获取选中单元格内容?

如何让一个单元格内容显示两行文字呢?

一个单元格内容(文本)作为另一个单元格中的变量

vb.net中如何获得DataGridView单元格内容