How do I shuffle an array in Swift?
Clash 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.
@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.
this is not specific to any language. Just apply any shuffling algorithm...
– Gabriele Petronella
Jun 3 '14 at 23:20