count
gibt eine IndexDistance
, die die Art der Beschreibung ist der Abstand zwischen zwei Sammlungsindizes. IndexDistance
ist erforderlich, um ein SignedInteger
zu sein, muss aber kein Int
sein und kann von Index
abweichen. Daher ist es nicht möglich den Bereich 0..<count - 1
zu erstellen.
Eine Lösung ist startIndex
und endIndex
verwenden anstelle von 0
und count
:
extension MutableCollection where Index == Int {
/// Shuffle the elements of `self` in-place.
mutating func shuffle() {
// empty and single-element collections don't shuffle
if count < 2 { return }
for i in startIndex ..< endIndex - 1 {
let j = Int(arc4random_uniform(UInt32(endIndex - i))) + i
if i != j {
swap(&self[i], &self[j])
}
}
}
}
Ein weiterer Vorteil ist, dass dies auch korrekt mit Array Scheiben arbeitet (wobei der Index des ersten Elements nicht notwendigerweise Null).
anzumerken, dass nach dem neuen "Swift API Design Guidelines", shuffle()
ist die "richtige" Name für einen mutierenden Shuffle-Methode, und shuffled()
für die nicht-Mutieren Gegenstück, die ein Array zurückgibt:
extension Collection {
/// Return a copy of `self` with its elements shuffled
func shuffled() -> [Iterator.Element] {
var list = Array(self)
list.shuffle()
return list
}
}
Update: Eine (noch allgemeinere) Swift 3-Version wurde in der Zwischenzeit zu How do I shuffle an array in Swift? hinzugefügt.
Für Swift 4 (Xcode 9) man hat den Anruf an die swap()
Funktion durch einen Aufruf der Methode swapAt()
der Sammlung zu ersetzen. Auch die Beschränkung des Index
Typ nicht mehr benötigt wird:
extension MutableCollection {
/// Shuffle the elements of `self` in-place.
mutating func shuffle() {
// empty and single-element collections don't shuffle
if count < 2 { return }
for i in indices.dropLast() {
let diff = distance(from: i, to: endIndex)
let j = index(i, offsetBy: numericCast(arc4random_uniform(numericCast(diff))))
swapAt(i, j)
}
}
}
SE-0173 Add MutableCollection.swapAt(_:_:)
über swapAt
für weitere Informationen.
https: // Stackoverflow.com/a/27261991/2303865 –
Mögliches Duplikat von [Wie mische ich ein Array in Swift?] (https://stackoverflow.com/questions/24026510/how-do-i-shuffle-an-array-in-swift) –
Die Frage ist obsolet, da die Referenz für Swift 3 aktualisiert wurde. –