How to get random element from a set in Swift?

Starting with Swift 4.2, you can use randomElement:

let random = set.randomElement()

Probably the best approach is advance which walks successor for you:

func randomElementIndex<T>(s: Set<T>) -> T {
    let n = Int(arc4random_uniform(UInt32(s.count)))
    let i = advance(s.startIndex, n)
    return s[i]
}

(EDIT: Heh; noticed you actually updated the question to include this answer before I added it to my answer... well, still a good idea and I learned something too. :D)

You can also walk the set rather than the indices (this was my first thought, but then I remembered advance).

func randomElement<T>(s: Set<T>) -> T {
    let n = Int(arc4random_uniform(UInt32(s.count)))
    for (i, e) in enumerate(s) {
        if i == n { return e }
    }
    fatalError("The above loop must succeed")
}

In swift 3

extension Set {
    public func randomObject() -> Element? {
        let n = Int(arc4random_uniform(UInt32(self.count)))
        let index = self.index(self.startIndex, offsetBy: n)
        return self.count > 0 ? self[index] : nil
    }
}

extension Set {
    func randomElement() -> Element? {
        return count == 0 ? nil : self[advance(self.startIndex, Int(arc4random()) % count)]
    }
}

Tags:

Set

Swift