count
renvoie un IndexDistance
qui est le type décrivant
la distance entre deux de collecte d'indices. IndexDistance
est
requises pour être un SignedInteger
, mais n'a pas besoin d'être un Int
et peut
être différent de Index
. Par conséquent, il n'est pas possible de créer
la gamme 0..<count - 1
.
Une solution est d'utiliser startIndex
et endIndex
au lieu de 0
et 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])
}
}
}
}
Un autre avantage est que cela fonctionne aussi correctement avec l'ensemble des tranches
(où l'indice du premier élément n'est pas nécessairement égale à zéro).
Notez que, selon la nouvelle Swift"API"instructions de Conception,
shuffle()
est le "bon" nom d'une mutation aléatoire de la méthode,
et shuffled()
pour les non-mutation homologue qui retourne un tableau:
extension Collection {
/// Return a copy of `self` with its elements shuffled
func shuffled() -> [Iterator.Element] {
var list = Array(self)
list.shuffle()
return list
}
}
Mise à jour: Un (encore plus général) de Swift, la version 3 a été ajouté à
Comment puis-je shuffle un tableau dans Swift? dans le même temps.
Pour Swift 4 (Xcode 9) on doit remplacer l'appel à l' swap()
fonction par un appel à l' swapAt()
méthode de la collection.
Aussi la restriction sur l' Index
type n'est plus nécessaire:
extension MutableCollection {
/// Shuffle the elements of `self` in-place.
mutating func shuffle() {
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)
}
}
}
Voir SE-0173 Ajouter MutableCollection.swapAt(_:_:)
pour plus d'informations sur l' swapAt
.
Comme de Swift 4.2 (Xcode 10, actuellement en version bêta), avec la mise en œuvre de
SE-0202 Aléatoire de l'Unification,
shuffle()
et shuffled()
font partie de la Swift de la bibliothèque standard.