What's the Best Way to Shuffle an NSMutableArray?

后端 未结 12 1681
太阳男子
太阳男子 2020-11-21 11:53

If you have an NSMutableArray, how do you shuffle the elements randomly?

(I have my own answer for this, which is posted below, but I\'m new to Cocoa an

12条回答
  •  说谎
    说谎 (楼主)
    2020-11-21 12:15

    A slightly improved and concise solution (compared to the top answers).

    The algorithm is the same and is described in literature as "Fisher-Yates shuffle".

    In Objective-C:

    @implementation NSMutableArray (Shuffle)
    // Fisher-Yates shuffle
    - (void)shuffle
    {
        for (NSUInteger i = self.count; i > 1; i--)
            [self exchangeObjectAtIndex:i - 1 withObjectAtIndex:arc4random_uniform((u_int32_t)i)];
    }
    @end
    

    In Swift 3.2 and 4.x:

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

    In Swift 3.0 and 3.1:

    extension Array {
        /// Fisher-Yates shuffle
        mutating func shuffle() {
            for i in stride(from: count - 1, to: 0, by: -1) {
                let j = Int(arc4random_uniform(UInt32(i + 1)))
                (self[i], self[j]) = (self[j], self[i])
            }
        }
    }
    

    Note: A more concise solution in Swift is possible from iOS10 using GameplayKit.

    Note: An algorithm for unstable shuffling (with all positions forced to change if count > 1) is also available

提交回复
热议问题