这是一个洗牌解决方案,当 count > 1 时,所有位置都被迫改变。
添加 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
然后你可以像这样洗牌:
[putNumbersUsed unstableShuffle];
这个解决方案:
Swift 3.2 和 Swift 4 等价物是:
extension Array {
mutating func unstableShuffle() {
for i in stride(from: count - 1, to: 0, by: -1) {
swapAt(i, Int(arc4random_uniform(UInt32(i))))
}
}
}
Swift 3.0 和 3.1 的等效版本是:
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)))])
}
}
}
注意:还可以使用常规洗牌算法(可能有相同位置的结果)