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

前端 未结 5 1461
不思量自难忘°
不思量自难忘° 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:33

    If you want to create a looping solution:

    let originalSet = Set(arrayLiteral: "a","b","c")
    var selectableSet = originalSet
    
    func repeatingRandomObject() -> String {
        if selectableSet.isEmpty {
            selectableSet = originalSet
        }
    
        return selectableSet.remove(selectableSet.randomElement()!)!
    }
    

    force unwrapping is kind of safe here, since we know that the result will never be nil. If you don't want to force unwrap:

    let originalSet = Set(arrayLiteral: "a","b","c")
    var selectableSet = originalSet
    
    func repeatingRandomObject() -> String? {
        if selectableSet.isEmpty {
            selectableSet = originalSet
        }
    
        guard let randomElement = selectableSet.randomElement() else { return nil }
        return selectableSet.remove(randomElement)
    }
    
    0 讨论(0)
  • 2020-12-12 08:40

    Set is a collection type that holds unique elements. Converting your notebooks array to Set also lets you take advantage of its randomElement function

    var aSet = Set(notebooks)
    
    let element = aSet.randomElement()
    aSet.remove(element)
    
    0 讨论(0)
  • 2020-12-12 08:41

    It is possible with shuffle:

    struct AnantShuffler<Base: MutableCollection> {
    
        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()
    
    0 讨论(0)
  • 2020-12-12 08:45

    Copy the array. Shuffle the copy. Now just keep removing the first element until the copy is empty. When it is empty, start over.

    Example:

    let arr = [1,2,3,4,5]
    var copy = [Int]()
    for _ in 1...30 { // just to demonstrate what happens
        if copy.isEmpty { copy = arr; copy.shuffle() }
        let element = copy.removeFirst() ; print(element, terminator:" ")
    }
    // 4 2 3 5 1 1 5 3 2 4 4 1 2 3 5 1 4 5 2 3 3 5 4 2 1 3 2 4 5 1
    
    0 讨论(0)
  • 2020-12-12 08:48

    You can try something like this,

    var notebookCovers = ["cover1", "cover2", "cover3", "cover4", "cover4", "cover6", "cover7", "cover8", "cover9", "cover10"]
    var tappedNotebooks: [String] = []
    func tapping() {
        let notebook  =  notebookCovers[Int.random(in: 0...notebookCovers.count - 1)]
        if tappedNotebooks.contains(notebook){
            print("already exists trying again!")
            tapping()
        } else {
            tappedNotebooks.append(notebook)
            print("appended", notebook)
        }
        if tappedNotebooks == notebookCovers {
            tappedNotebooks = []
            print("cleared Tapped notebooks")
        }
    }
    
    0 讨论(0)
提交回复
热议问题