.shuffle()和.shuffled()是Swift的一部分
原历史问题:
我如何随机或洗牌在Swift数组中的元素?例如,如果我的数组包含52张扑克牌,我想要洗牌数组以洗牌牌组。
.shuffle()和.shuffled()是Swift的一部分
原历史问题:
我如何随机或洗牌在Swift数组中的元素?例如,如果我的数组包含52张扑克牌,我想要洗牌数组以洗牌牌组。
当前回答
在Swift 4.2中,现在有一个可变shuffle和不可变shuffle的方法。你可以在这里阅读更多关于随机生成和数组的东西。
其他回答
以Nate的算法为例,我想看看Swift 2和协议扩展会是什么样子。
这是我想到的。
extension MutableCollectionType where Self.Index == Int {
mutating func shuffleInPlace() {
let c = self.count
for i in 0..<(c - 1) {
let j = Int(arc4random_uniform(UInt32(c - i))) + i
swap(&self[i], &self[j])
}
}
}
extension MutableCollectionType where Self.Index == Int {
func shuffle() -> Self {
var r = self
let c = self.count
for i in 0..<(c - 1) {
let j = Int(arc4random_uniform(UInt32(c - i))) + i
swap(&r[i], &r[j])
}
return r
}
}
现在,任何MutableCollectionType都可以使用这些方法,因为它使用Int作为索引
这是一些在playground上运行的代码。你不需要在实际的Xcode项目中导入Darwin。
import darwin
var a = [1,2,3,4,5,6,7]
func shuffle<ItemType>(item1: ItemType, item2: ItemType) -> Bool {
return drand48() > 0.5
}
sort(a, shuffle)
println(a)
这是如何在Swift 3.0中洗牌一个种子数组。
extension MutableCollection where Indices.Iterator.Element == Index {
mutating func shuffle() {
let c = count
guard c > 1 else { return }
for (firstUnshuffled , unshuffledCount) in zip(indices, stride(from: c, to: 1, by: -1)) {
srand48(seedNumber)
let number:Int = numericCast(unshuffledCount)
let r = floor(drand48() * Double(number))
let d: IndexDistance = numericCast(Int(r))
guard d != 0 else { continue }
let i = index(firstUnshuffled, offsetBy: d)
swap(&self[firstUnshuffled], &self[i])
}
}
}
在我的例子中,我在数组中交换对象时遇到了一些问题。然后我挠头,开始重新发明轮子。
// swift 3.0 ready
extension Array {
func shuffled() -> [Element] {
var results = [Element]()
var indexes = (0 ..< count).map { $0 }
while indexes.count > 0 {
let indexOfIndexes = Int(arc4random_uniform(UInt32(indexes.count)))
let index = indexes[indexOfIndexes]
results.append(self[index])
indexes.remove(at: indexOfIndexes)
}
return results
}
}
let shuffl = GKRandomSource.sharedRandom().arrayByShufflingObjects(in: arrayObject)