Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Shuffle/shuffled functions & Array extensions
// (c) 2014 Nate Cook, licensed under the MIT license
//
// Fisher-Yates shuffle as top-level functions and array extension methods
/// Shuffle the elements of `list`.
func shuffle<C: MutableCollectionType where C.Index == Int>(inout list: 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 a collection containing the shuffled elements of `list`.
func shuffled<C: MutableCollectionType where C.Index == Int>(var list: C) -> C {
shuffle(&list)
return list
}
extension Array {
/// Shuffle the elements of `self` in-place.
mutating func shuffle() {
for i in 0..<(count - 1) {
let j = Int(arc4random_uniform(UInt32(count - i))) + i
swap(&self[i], &self[j])
}
}
/// Return a copy of `self` with its elements shuffled
func shuffled() -> [T] {
var list = self
list.shuffle()
return list
}
}
// Example of global functions
var strings = ["one", "two", "three", "four", "five", "six"]
shuffle(&strings)
// e.g., strings == [four, six, three, two, five, one]
let shuffledStrings = shuffled(strings)
// e.g., shuffledStrings == [six, four, one, five, three, two]
// Example of array methods
var numbers = [1, 2, 3, 4, 5, 6, 7, 8]
numbers.shuffle()
// e.g., numbers == [6, 1, 8, 3, 2, 4, 7, 5]
let shuffledNumbers = numbers.shuffled()
// e.g., mixedup == [4, 2, 6, 8, 7, 3, 5, 1]
@cwagdev

This comment has been minimized.

Copy link

@cwagdev cwagdev commented Jun 15, 2015

Hey Nate, here's an attempt at making this in Swift 2 using Protocol Extensions.

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

What do you think?

@retendo

This comment has been minimized.

Copy link

@retendo retendo commented Apr 16, 2016

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
            if i != j {
                swap(&r[i], &r[j])
            }
        }
        return r
    }
}
@alexsolis23

This comment has been minimized.

Copy link

@alexsolis23 alexsolis23 commented Aug 22, 2018

this repeats elements, how can I prevent this? thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment