これはなに?
与えられた配列の要素をランダムにかつ重複なくとりだすstructです。
なお、全て取り出し終えると最初に戻って繰り返します。
永遠に...
struct RepeatingRandomIterator<T>: IteratorProtocol {
private let base: [T]
private var indexes: [Int] = []
init(base: [T]) {
self.base = base
}
mutating func next() -> T? {
if indexes.isEmpty {
indexes = (0..<base.count).shuffled()
}
return base[indexes.removeFirst()]
}
}
struct RepeatingRandomQueue<T>: Sequence {
private let base: [T]
init(_ base: [T]) {
self.base = base
}
func makeIterator() -> RepeatingRandomIterator<T> {
.init(base: base)
}
}
使い方
let array = [0, 1, 2, 3, 4, 5]
let randomQueue = RepeatingRandomQueue(array)
// 終了条件をきちんと決めましょう
// さもなくば永遠に繰り返します
zip(1...100, randomQueue)
.forEach { print($0.1) }
おまけ
あまりここに書いても意味ないけど、永遠に繰り返さないバージョン
永遠じゃない
struct RandomIterator<T>: IteratorProtocol {
private let base: [T]
private var indexes: [Int] = []
init(base: [T]) {
self.base = base
self.indexes = (0..<base.count).shuffled()
}
mutating func next() -> T? {
guard !indexes.isEmpty else { return nil }
return base[indexes.removeFirst()]
}
}
struct RandomQueue<T>: Sequence {
private let base: [T]
init(_ base: [T]) {
self.base = base
}
func makeIterator() -> RandomIterator<T> {
.init(base: base)
}
}
使い方
print(
Array(
RandomQueue("これはつまならいでしょ".map { $0 })
.map(String.init)
)
.joined()
)