Here are three different ways of adding a Fisher-Yates (fast and uniform) shuffle.
shuffle as a function
This is the simplest version: add this function anywhere at the top level and you\'ll be able to shuffle arrays and slices:
func shuffle(var list: C) -> C {
let c = count(list)
for i in 0..<(c - 1) {
let j = Int(arc4random_uniform(UInt32(c - i))) + i
swap(&list[i], &list[j])
}
return list
}
shuffle([1, 2, 3, 4, 5, 6, 7, 8]) // e.g., [6, 1, 8, 3, 2, 4, 7, 5]
shuffle([\"hello\", \"goodbye\", \"ciao\"]) // e.g., [\"ciao\", \"goodbye\", \"hello\"]
shuffle as a mutating array method
This extension will let you shuffle a mutable Array instance in place:
extension Array {
mutating func shuffle() {
for i in 0..<(count - 1) {
let j = Int(arc4random_uniform(UInt32(count - i))) + i
swap(&self[i], &self[j])
}
}
}
var numbers = [1, 2, 3, 4, 5, 6, 7, 8]
numbers.shuffle() // e.g., numbers == [6, 1, 8, 3, 2, 4, 7, 5]
shuffled as a non-mutating array method
This extension will let you retrieve a shuffled copy of an Array instance:
extension Array {
func shuffled() -> [T] {
var list = self
for i in 0..<(list.count - 1) {
let j = Int(arc4random_uniform(UInt32(list.count - i))) + i
swap(&list[i], &list[j])
}
return list
}
}
let numbers = [1, 2, 3, 4, 5, 6, 7, 8]
let mixedup = numbers.shuffled() // e.g., mixedup == [6, 1, 8, 3, 2, 4, 7, 5]