Force Shuffle NSMutableArray

前端 未结 6 959
深忆病人
深忆病人 2021-01-13 14:03

I have a NSMutableArray called putNumberUsed. It contains the following objects @\"blah1,@\"blah2\",@\"blah3\",@\"blah4\". I want to shuffle these objects randomly so for ex

相关标签:
6条回答
  • 2021-01-13 14:27

    Here is a shuffling solution with all positions forced to change when count > 1.

    Add a category like NSMutableArray+Shuffle.m:

    @implementation NSMutableArray (Shuffle)
    // Fisher-Yates shuffle variation with all positions forced to change
    - (void)unstableShuffle
    {
        for (NSInteger i = self.count - 1; i > 0; i--)
            // note: we use u_int32_t because `arc4random_uniform` doesn't support int64
            [self exchangeObjectAtIndex:i withObjectAtIndex:arc4random_uniform((u_int32_t)i)];
    }
    @end
    

    Then you can shuffle like:

    [putNumbersUsed unstableShuffle];
    

    This solution:

    • has no modulo bias
    • has no naive bias
    • has no sorting bias

    A Swift 3.2 and Swift 4 equivalent is:

    extension Array {
        mutating func unstableShuffle() {
            for i in stride(from: count - 1, to: 0, by: -1) {
                swapAt(i, Int(arc4random_uniform(UInt32(i))))
            }
        }
    }
    

    A Swift 3.0 and 3.1 equivalent is:

    extension Array {
        mutating func unstableShuffle() {
            for i in stride(from: count - 1, to: 0, by: -1) {
                swap(&self[i], &self[Int(arc4random_uniform(UInt32(i)))])
            }
        }
    }
    

    Note: An algorithm for regular shuffling (where a result with same positions being possible) is also available

    0 讨论(0)
  • 2021-01-13 14:37

    generate a random number for index

    int randomInt = arc4random() % [putNumberUsed count];
    [putNumberUsed objectAtIndex:randomInt];
    
    0 讨论(0)
  • 2021-01-13 14:38

    Use this:

    for (int i = 0; i < [putNumberUsed count]; i++) {
        int random = arc4random() % [putNumberUsed count]; 
        [putNumbersUsed exchangeObjectAtIndex:random withObjectAtIndex:i]; 
    }
    
    0 讨论(0)
  • 2021-01-13 14:39

    You can shuffle the object by using the following line of code,

    [putNumbersUsed exchangeObjectAtIndex:3 withObjectAtIndex:0];
    

    I think this may useful to you.

    0 讨论(0)
  • 2021-01-13 14:43

    I think, You can write a loop for that. Please check the following code,

    for (int i = 0; i < putNumberUsed.count; i++) {
        int randomInt1 = arc4random() % [putNumberUsed count];
        int randomInt2 = arc4random() % [putNumberUsed count];
        [putNumberUsed exchangeObjectAtIndex:randomInt1 withObjectAtIndex:randomInt2];
    }
    

    I this this may be useful to you.

    0 讨论(0)
  • 2021-01-13 14:50

    From iOS 10.x++ new concept of shuffle array is given by Apple,

    You need to import the framework :

    ObjeC

    #import <GameplayKit/GameplayKit.h>
    
    NSArray *shuffledArray = [yourArray shuffledArray];
    

    Swift

    import GameplayKit
    
    let shuffledArray = yourArray.shuffled()
    
    0 讨论(0)
提交回复
热议问题