How do I shuffle an array in Swift?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



How do I shuffle an array in Swift?



How do I randomize or shuffle the elements within an array in Swift? For example, if my array consists of 52 playing cards, I want to shuffle the array in order to shuffle the deck.





this is not specific to any language. Just apply any shuffling algorithm...
– Gabriele Petronella
Jun 3 '14 at 23:20





@Mithrandir That's not true. In Ruby one would go for array.shuffle. There's no need to implement your own version. I guess OP was looking for something similar.
– Oleander
Jun 4 '14 at 0:17


array.shuffle





be careful, though, do not use just any shuffle algorithm to shuffle a deck of cards.
– njzk2
Oct 17 '16 at 14:00




25 Answers
25



This answer details how to shuffle with a fast and uniform algorithm (Fisher-Yates) in Swift 4.2+ and how to add the same feature in the various previous versions of Swift. The naming and behavior for each Swift version matches the mutating and nonmutating sorting methods for that version.



Swift 4.2+



shuffle and shuffled are native starting Swift 4.2. Example usage:


shuffle


shuffled


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 4.0 and 4.1



These extensions add a shuffle() method to any mutable collection (arrays and unsafe mutable buffers) and a shuffled() method to any sequence:


shuffle()


shuffled()


extension MutableCollection
/// Shuffles the contents of this collection.
mutating func shuffle()
let c = count
guard c > 1 else return

for (firstUnshuffled, unshuffledCount) in zip(indices, stride(from: c, to: 1, by: -1))
// Change `Int` in the next line to `IndexDistance` in < Swift 4.1
let d: Int = numericCast(arc4random_uniform(numericCast(unshuffledCount)))
let i = index(firstUnshuffled, offsetBy: d)
swapAt(firstUnshuffled, i)




extension Sequence
/// Returns an array with the contents of this sequence, shuffled.
func shuffled() -> [Element]
var result = Array(self)
result.shuffle()
return result




Same usage as in Swift 4.2 examples above.



Swift 3



These extensions add a shuffle() method to any mutable collection and a shuffled() method to any sequence:


shuffle()


shuffled()


extension MutableCollection where Indices.Iterator.Element == Index
/// Shuffles the contents of this collection.
mutating func shuffle()
let c = count
guard c > 1 else return

for (firstUnshuffled , unshuffledCount) in zip(indices, stride(from: c, to: 1, by: -1))
// Change `Int` in the next line to `IndexDistance` in < Swift 3.2
let d: Int = numericCast(arc4random_uniform(numericCast(unshuffledCount)))
guard d != 0 else continue
let i = index(firstUnshuffled, offsetBy: d)
self.swapAt(firstUnshuffled, i)




extension Sequence
/// Returns an array with the contents of this sequence, shuffled.
func shuffled() -> [Iterator.Element]
var result = Array(self)
result.shuffle()
return result




Same usage as in Swift 4.2 examples above.



Swift 2



(obsolete language: you can't use Swift 2.x to publish on iTunes Connect starting July 2018)


extension MutableCollectionType where Index == Int
/// Shuffle the elements of `self` in-place.
mutating func shuffleInPlace()
// empty and single-element collections don't shuffle
if count < 2 return

for i in startIndex ..< endIndex - 1
let j = Int(arc4random_uniform(UInt32(count - i))) + i
guard i != j else continue
swap(&self[i], &self[j])




extension CollectionType
/// Return a copy of `self` with its elements shuffled.
func shuffle() -> [Generator.Element]
var list = Array(self)
list.shuffleInPlace()
return list




Usage:


[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



(obsolete language: you can't use Swift 1.x to publish on iTunes Connect starting July 2018)


shuffle



This extension will let you shuffle a mutable Array instance in place:


Array


extension Array
mutating func shuffle()
if count < 2 return
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



This extension will let you retrieve a shuffled copy of an Array instance:


Array


extension Array
func shuffled() -> [T]
if count < 2 return self
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]





@RobertBrax Good question - updated the answer!
– Nate Cook
Nov 6 '14 at 15:59





In case you want the function version in Swift 1.2, it needs a bit of updating as countElements is gone, and it’s replacement, count, now returns a T.Index.Distance so the constraint needs to be on C.Index.Distance == Int. This version should work: gist.github.com/airspeedswift/03d07a9dc86fabdc370f
– Airspeed Velocity
Apr 4 '15 at 22:07


countElements


count


T.Index.Distance


C.Index.Distance == Int





Those are the actual output—Fisher-Yates should return an unbiased random permutation of the source, so there's no requirement that a particular element should move. There is a guarantee that no element moves more than once, but sometimes the "move" is to the same index. The simplest case is to think about [1, 2].shuffled()—should that return [2, 1] every time?
– Nate Cook
May 11 '15 at 15:42



[1, 2].shuffled()


[2, 1]





@Jan: Yes, add guard i != j else continue before the swap. I filed a radar, but the new behavior is intentional.
– Nate Cook
Sep 10 '15 at 12:40


guard i != j else continue





Actually shuffleInPlace can crash if the collection indices do not start at zero, e.g. for an array slice. for i in 0..<count - 1 should be for i in startIndex ..< endIndex - 1 (and then the conversion to Swift 3 becomes almost trivial).
– Martin R
Sep 14 '16 at 12:01


shuffleInPlace


for i in 0..<count - 1


for i in startIndex ..< endIndex - 1



Edit: As noted in other answers, Swift 4.2 finally adds random number generation to the standard library, complete with array shuffling.



However, the GKRandom / GKRandomDistribution suite in GameplayKit can still be useful with the new RandomNumberGenerator protocol — if you add extensions to the GameplayKit RNGs to conform to the new standard library protocol, you can easily get:


GKRandom


GKRandomDistribution


RandomNumberGenerator



...and still make use of the nice new "native" random APIs in Swift.



The rest of this answer concerns such RNGs and/or their use in older Swift compilers.



There are some good answers here already, as well as some good illustrations of why writing your own shuffle can be error-prone if you're not careful.



In iOS 9, macOS 10.11, and tvOS 9 (or later), you don't have to write your own. There's an efficient, correct implementation of Fisher-Yates in GameplayKit (which, despite the name, is not just for games).



If you just want a unique shuffle:


let shuffled = GKRandomSource.sharedRandom().arrayByShufflingObjects(in: array)



If you want to be able to replicate a shuffle or series of shuffles, choose and seed a specific random source; e.g.


let lcg = GKLinearCongruentialRandomSource(seed: mySeedValue)
let shuffled = lcg.arrayByShufflingObjects(in: array)



In iOS 10 / macOS 10.12 / tvOS 10, there's also a convenience syntax for shuffling via an extension on NSArray. Of course, that's a little cumbersome when you're using a Swift Array (and it loses its element type on coming back to Swift):


NSArray


Array


let shuffled1 = (array as NSArray).shuffled(using: random) // -> [Any]
let shuffled2 = (array as NSArray).shuffled() // use default random source



But it's pretty easy to make a type-preserving Swift wrapper for it:


extension Array
func shuffled(using source: GKRandomSource) -> [Element]
return (self as NSArray).shuffled(using: source) as! [Element]

func shuffled() -> [Element]
return (self as NSArray).shuffled() as! [Element]


let shuffled3 = array.shuffled(using: random)
let shuffled4 = array.shuffled()





Makes me wonder what other helpful utilities can be found in GameplayKit that I have never explored!
– Richard Venable
Oct 26 '15 at 15:02





Graph search, tree search, rule systems... lots of stuff that's helpful both in game design and otherwise.
– rickster
Oct 26 '15 at 15:07





In Swift 3/iOS 10, this has been changed to: let shuffled = lcg.arrayByShufflingObjects(in: array)
– Evan Pon
Nov 16 '16 at 21:38



let shuffled = lcg.arrayByShufflingObjects(in: array)



In Swift 2.0, GameplayKit may come to the rescue! (supported by iOS9 or later)


import GameplayKit

func shuffle()
array = GKRandomSource.sharedRandom().arrayByShufflingObjectsInArray(array)





importing GameplayKit just to get shuffled array doesn't sound like a great idea
– Lope
Apr 28 '17 at 18:08





Why? It's part of the system, doesn't add to the binary.
– Abizern
Oct 7 '17 at 4:16





You can also scope the import to simply import GameplayKit.GKRandomSource
– JRG-Developer
Nov 14 '17 at 12:56


import GameplayKit.GKRandomSource



Here's something possibly a little shorter:


sorted(a) _, _ in arc4random() % 2 == 0





@moby The sort function needs a closure to order elements. This closure takes two parameters (elem1, elem2) and must return true if the first value should appear before the second value, and false otherwise. If we return a random boolean instead... then we just mix up the whole thing :)
– Jean Le Moignan
Aug 9 '14 at 19:56



sort





Any mathematician here to confirm or disprove?
– Jean Le Moignan
Aug 26 '14 at 1:22





As pjs pointed out in response to another very similar answer, this will not generate uniform distribution of results. Use Fisher-Yates Shuffle as shown in Nate Cook's answer.
– Rob
Oct 20 '14 at 5:36





This is a clever trick, but is abysmal in terms of quality of the shuffle. For one, this closure should use arc4random_uniform(), becuse it's currently subject to the modulo bias. Secondly,the output depends very strongly on the sorting algorithm (which isn't known to us without looking at the source).
– Alexander
Aug 8 '16 at 20:48


arc4random_uniform()





Continuing with this simpler approach, this seems to work quite nicely: collection.sorted _,_ in arc4random_uniform(1) == 0
– markiv
Oct 6 '17 at 9:15



collection.sorted _,_ in arc4random_uniform(1) == 0



Taking Nate's algorithm I wanted to see how this would look with Swift 2 and protocol extensions.



This is what I came up with.


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




Now, any MutableCollectionType can use these methods given it uses Int as an Index


MutableCollectionType


Int


Index



In my case, I had some problems of swapping objects in Array. Then I scratched my head and go for reinventing the wheel.


// 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





This is a version of Nate's implementation of the Fisher-Yates shuffle for Swift 4
(Xcode 9).


extension MutableCollection
/// Shuffle the elements of `self` in-place.
mutating func shuffle()
for i in indices.dropLast()
let diff = distance(from: i, to: endIndex)
let j = index(i, offsetBy: numericCast(arc4random_uniform(numericCast(diff))))
swapAt(i, j)




extension Collection
/// Return a copy of `self` with its elements shuffled
func shuffled() -> [Element]
var list = Array(self)
list.shuffle()
return list




The changes are:


Indices.Iterator.Element == Index


Collection


swapAt()


MutableCollection.swapAt(_:_:)


Element


Iterator.Element



This is what I use:


func newShuffledArray(array:NSArray) -> NSArray
var mutableArray = array.mutableCopy() as! NSMutableArray
var count = mutableArray.count
if count>1
for var i=count-1;i>0;--i
mutableArray.exchangeObjectAtIndex(i, withObjectAtIndex: Int(arc4random_uniform(UInt32(i+1))))


return mutableArray as NSArray



Swift 4
Shuffle the elements of an array in a for loop where i is the mixing ratio


var cards = [Int]() //Some Array
let i = 4 // is the mixing ratio
func shuffleCards()
for _ in 0 ..< cards.count * i
let card = cards.remove(at: Int(arc4random_uniform(UInt32(cards.count))))
cards.insert(card, at: Int(arc4random_uniform(UInt32(cards.count))))




Or with extension Int


func shuffleCards()
for _ in 0 ..< cards.count * i
let card = cards.remove(at: cards.count.arc4random)
cards.insert(card, at: cards.count.arc4random)


extension Int
var arc4random: Int
if self > 0
print("Arc for random positiv self (Int(arc4random_uniform(UInt32(self))))")
return Int(arc4random_uniform(UInt32(self)))
else if self < 0
print("Arc for random negotiv self (-Int(arc4random_uniform(UInt32(abs(self)))))")
return -Int(arc4random_uniform(UInt32(abs(self))))
else
print("Arc for random equal 0")
return 0





Swift 3 solution, following @Nate Cook answer: (work if the index starts with 0, see comments below)


extension Collection
/// Return a copy of `self` with its elements shuffled
func shuffle() -> [Generator.Element]
var list = Array(self)
list.shuffleInPlace()
return list


extension MutableCollection where Index == Int
/// Shuffle the elements of `self` in-place.
mutating func shuffleInPlace()
// empty and single-element collections don't shuffle
if count < 2 return
let countInt = count as! Int

for i in 0..<countInt - 1
let j = Int(arc4random_uniform(UInt32(countInt - i))) + i
guard i != j else continue
swap(&self[i], &self[j])







This can crash if the collection indices do start at 0, e.g. for an array slice. Try to run var a = [1, 2, 3, 4, 5, 6][3..<6]; a.shuffleInPlace() several times. – See stackoverflow.com/a/37843901/1187415 for a correct solution.
– Martin R
Sep 14 '16 at 11:55



var a = [1, 2, 3, 4, 5, 6][3..<6]; a.shuffleInPlace()



This is how its done in a Simplest way.import Gamplaykit to your VC and use the below code. Tested in Xcode 8.


import Gamplaykit


import GameplayKit

let array: NSArray = ["Jock", "Ellie", "Sue Ellen", "Bobby", "JR", "Pamela"]

override func viewDidLoad()
super.viewDidLoad()

print(array.shuffled())



If you want to get a shuffled String from an Array you can use below code..


func suffleString()

let ShuffleArray = array.shuffled()

suffleString.text = ShuffleArray.first as? String

print(suffleString.text!)




With Swift 3, if you want to shuffle an array in place or get a new shuffled array from an array, AnyIterator can help you. The idea is to create an array of indices from your array, to shuffle those indices with an AnyIterator instance and swap(_:_:) function and to map each element of this AnyIterator instance with the array's corresponding element.


AnyIterator


AnyIterator


swap(_:_:)


AnyIterator



The following Playground code shows how it works:


import Darwin // required for arc4random_uniform

let array = ["Jock", "Ellie", "Sue Ellen", "Bobby", "JR", "Pamela"]
var indexArray = Array(array.indices)
var index = indexArray.endIndex

let indexIterator: AnyIterator<Int> = AnyIterator
guard let nextIndex = indexArray.index(index, offsetBy: -1, limitedBy: indexArray.startIndex)
else return nil

index = nextIndex
let randomIndex = Int(arc4random_uniform(UInt32(index)))
if randomIndex != index
swap(&indexArray[randomIndex], &indexArray[index])


return indexArray[index]


let newArray = indexIterator.map array[$0]
print(newArray) // may print: ["Jock", "Ellie", "Sue Ellen", "JR", "Pamela", "Bobby"]



You can refactor the previous code and create a shuffled() function inside an Array extension in order to get a new shuffled array from an array:


shuffled()


Array


import Darwin // required for arc4random_uniform

extension Array

func shuffled() -> Array<Element>
var indexArray = Array<Int>(indices)
var index = indexArray.endIndex

let indexIterator = AnyIterator<Int>
guard let nextIndex = indexArray.index(index, offsetBy: -1, limitedBy: indexArray.startIndex)
else return nil

index = nextIndex
let randomIndex = Int(arc4random_uniform(UInt32(index)))
if randomIndex != index
swap(&indexArray[randomIndex], &indexArray[index])


return indexArray[index]


return indexIterator.map self[$0]





Usage:


let array = ["Jock", "Ellie", "Sue Ellen", "Bobby", "JR", "Pamela"]
let newArray = array.shuffled()
print(newArray) // may print: ["Bobby", "Pamela", "Jock", "Ellie", "JR", "Sue Ellen"]


let emptyArray = [String]()
let newEmptyArray = emptyArray.shuffled()
print(newEmptyArray) // prints:



As an alternative to the previous code, you can create a shuffle() function inside an Array extension in order to shuffle an array in place:


shuffle()


Array


import Darwin // required for arc4random_uniform

extension Array

mutating func shuffle()
var indexArray = Array<Int>(indices)
var index = indexArray.endIndex

let indexIterator = AnyIterator<Int>
guard let nextIndex = indexArray.index(index, offsetBy: -1, limitedBy: indexArray.startIndex)
else return nil

index = nextIndex
let randomIndex = Int(arc4random_uniform(UInt32(index)))
if randomIndex != index
swap(&indexArray[randomIndex], &indexArray[index])


return indexArray[index]


self = indexIterator.map self[$0]





Usage:


var mutatingArray = ["Jock", "Ellie", "Sue Ellen", "Bobby", "JR", "Pamela"]
mutatingArray.shuffle()
print(mutatingArray) // may print ["Sue Ellen", "Pamela", "Jock", "Ellie", "Bobby", "JR"]



Form the article of Fisher–Yates shuffle on Wikipedia



Swift 3.1,4.0



a). Pencil-and-paper method :


func shuffle<T>(_ array:inout [T])

var temp = [T]()

for _ in array

/*Generating random number with length*/
let random = arc4random_uniform(UInt32(array.count))
/*Take the element from array*/
let elementTaken = array[Int(random)]
/*Append it to new tempArray*/
temp.append(elementTaken)
/*Remove the element from array*/
array.remove(at: Int(random))


/* array = tempArray*/
array = temp



b). Modern method:(Durstenfeld's version)


func shuffle<T>(_ array:inout [T])

var length = array.count

for _ in array

/*Generating random number with length*/
let random = arc4random_uniform(UInt32(length))
/*Check before index of two elements not same*/
if length-1 != Int(random)
swap(&array[length-1], &array[Int(random)])


length -= 1




Extension:


Extension:



a). Pencil-and-paper method :


extension Array

mutating func shuffled()

var temp = [Element]()

for _ in self

/*Generating random number with length*/
let random = arc4random_uniform(UInt32(self.count))
/*Take the element from array*/
let elementTaken = self[Int(random)]
/*Append it to new tempArray*/
temp.append(elementTaken)
/*Remove the element from array*/
self.remove(at: Int(random))


/* array = tempArray*/
self = temp




b). Modern method:(Durstenfeld's version)


extension Array

mutating func shuffled()

var length = self.count

for _ in self

/*Generating random number with length*/
let random = arc4random_uniform(UInt32(length))

/*Check before index of two elements not same*/

if length-1 != Int(random)

/*Swaping elements, If same index then there is no swap*/
// swap(&self[length-1], &self[Int(random)]) -> Swift 3.0
self.swapAt(length-1, Int(random)) //-> Swift 4.0



length -= 1





Reference :


/* By using shuffle functions*/
var a = [1,2,3,4,5,6,7,8,9,10]

for _ in 1...10

self.shuffle(&a)

/*For shuffled extension, a.shuffled()*/
print(a)



Note:
You can use empty array also.



Output:



[6, 2, 10, 5, 1, 8, 9, 4, 3, 7]



[7, 1, 9, 8, 2, 10, 5, 6, 4, 3]



[8, 9, 6, 10, 5, 2, 7, 4, 3, 1]



[10, 1, 7, 4, 8, 9, 3, 5, 2, 6]



[8, 1, 6, 9, 3, 7, 4, 5, 10, 2]



[4, 3, 7, 9, 1, 5, 8, 6, 10, 2]



[7, 3, 4, 9, 10, 1, 6, 5, 2, 8]



[3, 6, 2, 4, 5, 8, 9, 7, 1, 10]



[5, 1, 2, 10, 6, 9, 7, 3, 8, 4]



[7, 9, 3, 8, 2, 1, 5, 4, 6, 10]



Please let me know if any queries, Other Swift version will be check soon.



You can use generic swap function as well and implement mentioned Fisher-Yates:


swap


for idx in 0..<arr.count
let rnd = Int(arc4random_uniform(UInt32(idx)))
if rnd != idx
swap(&arr[idx], &arr[rnd])




or less verbose:


for idx in 0..<steps.count
swap(&steps[idx], &steps[Int(arc4random_uniform(UInt32(idx)))])





This suffers from, at the very least, a serious off by one error described here whereby a value is always swapped from its original position. This is remedied with let rnd = Int(arc4random_uniform(UInt32(idx + 1))). Also, in FY, you generally iterate from arr.count - 1 down to 1 (or if you iterate from 0 to arr.count - 1, you pick index like Nate shows in accepted answer). See Modern Algorithm section of Fisher-Yates discussion.
– Rob
Oct 20 '14 at 6:21



let rnd = Int(arc4random_uniform(UInt32(idx + 1)))


arr.count - 1


1


0


arr.count - 1



works!!. organisms is the array to shuffle.


extension Array

/** Randomizes the order of an array's elements. */
mutating func shuffle()

for _ in 0..<10

sort (_,_) in arc4random() < arc4random()




var organisms = [
"ant", "bacteria", "cougar",
"dog", "elephant", "firefly",
"goat", "hedgehog", "iguana"]

print("Original: (organisms)")

organisms.shuffle()

print("Shuffled: (organisms)")





Love the conciseness, thanks!
– Federico Zanetello
May 6 at 16:48



This is how to shuffle one array with a seed in 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])




let shuffl = GKRandomSource.sharedRandom().arrayByShufflingObjects(in: arrayObject)



This is what I use:


import GameplayKit

extension Collection
func shuffled() -> [Iterator.Element]
let shuffledArray = (self as? NSArray)?.shuffled()
let outputArray = shuffledArray as? [Iterator.Element]
return outputArray ??

mutating func shuffle()
if let selfShuffled = self.shuffled() as? Self
self = selfShuffled




// Usage example:

var numbers = [1,2,3,4,5]
numbers.shuffle()

print(numbers) // output example: [2, 3, 5, 4, 1]

print([10, "hi", 9.0].shuffled()) // output example: [hi, 10, 9]



Simple Example:


extension Array
mutating func shuffled()
for _ in self
// generate random indexes that will be swapped
var (a, b) = (Int(arc4random_uniform(UInt32(self.count - 1))), Int(arc4random_uniform(UInt32(self.count - 1))))
if a == b // if the same indexes are generated swap the first and last
a = 0
b = self.count - 1

swap(&self[a], &self[b])




var array = [1,2,3,4,5,6,7,8,9,10]
array.shuffled()
print(array) // [9, 8, 3, 5, 7, 6, 4, 2, 1, 10]



Working Array Extension (mutating & non-mutating)



The top answer is deprecated, so I took it upon myself to create my own extension to shuffle an array in the newest version of Swift, Swift 4.1 (Xcode 9):


extension Array

// Non-mutating shuffle
var shuffled : Array
let totalCount : Int = self.count
var shuffledArray : Array =
var count : Int = totalCount
var tempArray : Array = self
for _ in 0..<totalCount
let randomIndex : Int = Int(arc4random_uniform(UInt32(count)))
let randomElement : Element = tempArray.remove(at: randomIndex)
shuffledArray.append(randomElement)
count -= 1

return shuffledArray


// Mutating shuffle
mutating func shuffle()
let totalCount : Int = self.count
var shuffledArray : Array =
var count : Int = totalCount
var tempArray : Array = self
for _ in 0..<totalCount
let randomIndex : Int = Int(arc4random_uniform(UInt32(count)))
let randomElement : Element = tempArray.remove(at: randomIndex)
shuffledArray.append(randomElement)
count -= 1

self = shuffledArray



[Array] -> [Array]


let array = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

print(array.shuffled)



This prints array in a random order.


array


[Array] = [Array]


var array = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

array.shuffle()
// The array has now been mutated and contains all of its initial
// values, but in a randomized shuffled order

print(array)



This prints array in its current order, which has already been randomly shuffled.


array



Hopes this works for everybody, if you have any questions, suggestions, or comments, feel free to ask!



In SWIFT 4


func createShuffledSequenceOfNumbers(max:UInt)->[UInt]

var array:[UInt]! =
var myArray:[UInt]! =
for i in 1...max
myArray.append(i)

for i in 1...max
array.append(i)

var tempArray:[Int]! =
for index in 0...(myArray.count - 1)

var isNotFinded:Bool = true
while(isNotFinded)

let randomNumber = arc4random_uniform(UInt32(myArray.count))
let randomIndex = Int(randomNumber)

if(!tempArray.contains(randomIndex))
tempArray.append(randomIndex)

array[randomIndex] = myArray[index]
isNotFinded = false




return array



In Swift 4.2, there is now a method for both a mutable shuffle and immutable shuffled. You can read more about the random generation and array stuff here.


shuffle


shuffled



If you want to use simple Swift For loop function use this ->


var arrayItems = ["A1", "B2", "C3", "D4", "E5", "F6", "G7", "H8", "X9", "Y10", "Z11"]
var shuffledArray = [String]()

for i in 0..<arrayItems.count

let randomObject = Int(arc4random_uniform(UInt32(items.count)))

shuffledArray.append(items[randomObject])

items.remove(at: randomObject)


print(shuffledArray)



Swift Array suffle using extension ->


extension Array
// Order Randomize
mutating func shuffle()
for _ in 0..<count
sort (_,_) in arc4random() < arc4random()





Here's some code that runs in playground. You won't need to import Darwin in an actual Xcode project.


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)





This gives a non-uniform distribution of the results. It also will be O(n log n), where a Fisher-Yates shuffle would give uniformly distributed results in O(n) time.
– pjs
Jun 4 '14 at 3:54





Also drand48() gives the same pseudo random numbers everytime, unless you set a seed with like srand48(Int(arc4random()))
– Kametrixom
May 30 '15 at 21:08



drand48()


srand48(Int(arc4random()))



It stop at "swap(&self[i], &self[j])" when I upgrade the xCode version to 7.4 beta.

fatal error: swapping a location with itself is not supported



I found the reason that i = j (function of swap will exploded)



So I add a condition as below


if (i != j)
swap(&list[i], &list[j])



YA! It's OK for me.





This appears to be a comment on Chris's answer, not an answer to the original question.
– Mogsdad
Aug 26 '15 at 3:32






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard