I have the following array:
var notebookCovers = [\"cover1\", \"cover2\", \"cover3\", \"cover4\", \"cover4\", \"cover6\", \"cover7\", \"cover8\", \"cover9\"
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)
}
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)
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()
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
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")
}
}