Get a random unique element from an Array until all elements have been picked in Swift

前端 未结 5 1465
不思量自难忘°
不思量自难忘° 2020-12-12 08:32

I have the following array:

var notebookCovers = [\"cover1\", \"cover2\", \"cover3\", \"cover4\", \"cover4\", \"cover6\", \"cover7\", \"cover8\", \"cover9\"         


        
5条回答
  •  死守一世寂寞
    2020-12-12 08:41

    It is possible with shuffle:

    struct AnantShuffler {
    
        private var collection: Base
        private var index: Base.Index
    
        public init?(collection: Base) {
            guard !collection.isEmpty else {
                return nil
            }
            self.collection = collection
            self.index = collection.startIndex
        }
    
        public mutating func next() -> Base.Iterator.Element {
            let result = collection[index]
            collection.formIndex(after: &index)
            if index == collection.endIndex {
                collection.shuffle()
                index = collection.startIndex
            }
            return result
        }
    }
    
    fileprivate 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)) {
                let d: Int = numericCast(arc4random_uniform(numericCast(unshuffledCount)))
                let i = index(firstUnshuffled, offsetBy: d)
                swapAt(firstUnshuffled, i)
            }
        }
    }
    

    Use:

    let shuffler = AnantShuffler(collection: ["c1","c2","c3"].shuffled())
    shuffler?.next()
    

提交回复
热议问题