How do I shuffle an array in Swift? -


how randomize or shuffle elements within array in swift? example, if array consists of 52 playing cards, want shuffle array in order shuffle deck.

this answer details how add fisher-yates (fast uniform) shuffle in various versions of swift. swift 3 & 4 versions permissive, @ least work arrays. naming , behavior each swift version matches mutating , nonmutating sorting methods version.

swift 4

these extensions add shuffle() method mutable collection (arrays , unsafe mutable buffers) , shuffled() method sequence:

extension mutablecollection {     /// shuffles contents of collection.     mutating func shuffle() {         let c = count         guard c > 1 else { return }          (firstunshuffled, unshuffledcount) in zip(indices, stride(from: c, to: 1, by: -1)) {             let d: indexdistance = numericcast(arc4random_uniform(numericcast(unshuffledcount)))             let = index(firstunshuffled, offsetby: d)             swapat(firstunshuffled, i)         }     } }  extension sequence {     /// returns array contents of sequence, shuffled.     func shuffled() -> [element] {         var result = array(self)         result.shuffle()         return result     } }  let x = [1, 2, 3].shuffled() // x == [2, 3, 1]  let fivestrings = stride(from: 0, through: 100, by: 5).map(string.init).shuffled() // fivestrings == ["20", "45", "70", "30", ...]  var numbers = [1, 2, 3, 4] numbers.shuffle() // numbers == [3, 2, 1, 4] 

swift 3

these extensions add shuffle() method mutable collection , shuffled() method sequence:

extension mutablecollection indices.iterator.element == index {     /// shuffles contents of collection.     mutating func shuffle() {         let c = count         guard c > 1 else { return }          (firstunshuffled , unshuffledcount) in zip(indices, stride(from: c, to: 1, by: -1)) {             let d: indexdistance = numericcast(arc4random_uniform(numericcast(unshuffledcount)))             guard d != 0 else { continue }             let = index(firstunshuffled, offsetby: d)             swap(&self[firstunshuffled], &self[i])         }     } }  extension sequence {     /// returns array contents of sequence, shuffled.     func shuffled() -> [iterator.element] {         var result = array(self)         result.shuffle()         return result     } }  let x = [1, 2, 3].shuffled() // x == [2, 3, 1]  let fivestrings = stride(from: 0, through: 100, by: 5).map(string.init).shuffled() // fivestrings == ["20", "45", "70", "30", ...]  var numbers = [1, 2, 3, 4] numbers.shuffle() // numbers == [3, 2, 1, 4] 

swift 2

extension mutablecollectiontype index == int {     /// shuffle elements of `self` in-place.     mutating func shuffleinplace() {         // empty , single-element collections don't shuffle         if count < 2 { return }          in startindex ..< endindex - 1 {             let j = int(arc4random_uniform(uint32(count - i))) +             guard != j else { continue }             swap(&self[i], &self[j])         }     } }  extension collectiontype {     /// return copy of `self` elements shuffled.     func shuffle() -> [generator.element] {         var list = array(self)         list.shuffleinplace()         return list     } }  [1, 2, 3].shuffle() // [2, 3, 1]  let fivestrings = 0.stride(through: 100, by: 5).map(string.init).shuffle() // ["20", "45", "70", "30", ...]  var numbers = [1, 2, 3, 4] numbers.shuffleinplace() // [3, 2, 1, 4] 

swift 1.2

shuffle function

this simplest version: add function anywhere @ top level , you'll able shuffle arrays , slices:

func shuffle<c: mutablecollectiontype c.index == int>(var list: c) -> c {     let c = count(list)     if c < 2 { return list }     in 0..<(c - 1) {         let j = int(arc4random_uniform(uint32(c - 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 mutating array method

this extension let shuffle mutable array instance in place:

extension array {     mutating func shuffle() {         if count < 2 { return }         in 0..<(count - 1) {             let j = int(arc4random_uniform(uint32(count - 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 non-mutating array method

this extension let retrieve shuffled copy of array instance:

extension array {     func shuffled() -> [t] {         if count < 2 { return self }         var list = self         in 0..<(list.count - 1) {             let j = int(arc4random_uniform(uint32(list.count - 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] 

Comments

Popular posts from this blog

php - Permission denied. Laravel linux server -

google bigquery - Delta between query execution time and Java query call to finish -

python - Pandas two dataframes multiplication? -