从数组中获取随机的唯一元素,直到在Swift中选择了所有元素

时间:2019-02-21 13:02:40

标签: ios arrays swift

我有以下数组:

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

和一个UIButton,当按下它时,它会使用数组的元素之一生成一个新的UIImage

我需要做的是每次点击按钮以从数组中生成随机但唯一的元素(无需重复元素),直到它们全部被选中,然后再次重新启动数组。

到目前为止,我得到了一个随机元素,但是它被重复了,我无法弄清楚如何处理,因此每次都能获得唯一的图像

func createNewNotebook() {
    let newNotebook = Notebook()
    let randomInt = randomNumber()
    newNotebook.coverImageString = notebookCovers[randomInt]
    notebooks.insert(newNotebook, at: 0)
    collectionView.reloadData()
}

func randomNumber() -> Int {
    var previousNumber = arc4random_uniform(UInt32(notebookCovers.count))   
    var randomNumber = arc4random_uniform(UInt32(notebookCovers.count - 1)) 
    notebookCovers.shuffle()
    if randomNumber == previousNumber {
        randomNumber = UInt32(notebookCovers.count - 1)
    }
    previousNumber = randomNumber
    return Int(randomNumber)
}

5 个答案:

答案 0 :(得分:5)

Set是包含唯一元素的集合类型。将notebooks数组转换为Set还可让您利用其randomElement函数

var aSet = Set(notebooks)

let element = aSet.randomElement()
aSet.remove(element)

答案 1 :(得分:1)

如果要创建循环解决方案:

let originalSet = Set(arrayLiteral: "a","b","c")
var selectableSet = originalSet

func repeatingRandomObject() -> String {
    if selectableSet.isEmpty {
        selectableSet = originalSet
    }

    return selectableSet.remove(selectableSet.randomElement()!)!
}
在这里

力展开是安全的,因为我们知道结果永远不会为零。如果您不想强行打开包装:

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

答案 2 :(得分:1)

复制数组。随机播放副本。现在只需继续删除第一个元素,直到副本为空。空时,重新开始。

示例:

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

答案 3 :(得分:0)

您可以尝试这样的事情

C

答案 4 :(得分:0)

可以随机播放

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

使用:

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