Comment puis-je randomiser ou mélanger les éléments d'un tableau dans Swift? Par exemple, si mon tableau se compose de 52 cartes à jouer, je veux mélanger le tableau afin de mélanger le paquet.
Cette réponse explique comment mélanger avec un algorithme rapide et uniforme (Fisher-Yates) dans Swift 4.2+ et comment ajouter la même fonctionnalité dans les différentes versions précédentes de Swift. La dénomination et le comportement de chaque version Swift correspondent aux méthodes de tri en mutation et en mutation de cette version.
shuffle
et shuffled
sont natifs à partir de Swift 4.2. Exemple d'utilisation:
let x = [1, 2, 3].shuffled()
// x == [2, 3, 1]
let fiveStrings = stride(from: 0, through: 100, by: 5).map(String.init).shuffled()
// fiveStrings == ["20", "45", "70", "30", ...]
var numbers = [1, 2, 3, 4]
numbers.shuffle()
// numbers == [3, 2, 1, 4]
Ces extensions ajoutent une méthode shuffle()
à toute collection modifiable (tableaux et tampons non sécurisés) et une méthode shuffled()
à toute séquence:
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)) {
// Change `Int` in the next line to `IndexDistance` in < Swift 4.1
let d: Int = numericCast(arc4random_uniform(numericCast(unshuffledCount)))
let i = index(firstUnshuffled, offsetBy: d)
swapAt(firstUnshuffled, i)
}
}
}
extension Sequence {
/// Returns an array with the contents of this sequence, shuffled.
func shuffled() -> [Element] {
var result = Array(self)
result.shuffle()
return result
}
}
Même utilisation que dans Swift 4.2 exemples ci-dessus.
Ces extensions ajoutent une méthode shuffle()
à toute collection mutable et une méthode shuffled()
à toute séquence:
extension MutableCollection where Indices.Iterator.Element == Index {
/// 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)) {
// Change `Int` in the next line to `IndexDistance` in < Swift 3.2
let d: Int = numericCast(arc4random_uniform(numericCast(unshuffledCount)))
guard d != 0 else { continue }
let i = index(firstUnshuffled, offsetBy: d)
self.swapAt(firstUnshuffled, i)
}
}
}
extension Sequence {
/// Returns an array with the contents of this sequence, shuffled.
func shuffled() -> [Iterator.Element] {
var result = Array(self)
result.shuffle()
return result
}
}
Même utilisation que dans Swift 4.2 exemples ci-dessus.
(langue obsolète: vous ne pouvez pas utiliser Swift 2.x pour publier sur iTunes Connect à partir de juillet 2018)
extension MutableCollectionType where Index == Int {
/// Shuffle the elements of `self` in-place.
mutating func shuffleInPlace() {
// empty and single-element collections don't shuffle
if count < 2 { return }
for i in startIndex ..< endIndex - 1 {
let j = Int(arc4random_uniform(UInt32(count - i))) + i
guard i != j else { continue }
swap(&self[i], &self[j])
}
}
}
extension CollectionType {
/// Return a copy of `self` with its elements shuffled.
func shuffle() -> [Generator.Element] {
var list = Array(self)
list.shuffleInPlace()
return list
}
}
Usage:
[1, 2, 3].shuffle()
// [2, 3, 1]
let fiveStrings = 0.stride(through: 100, by: 5).map(String.init).shuffle()
// ["20", "45", "70", "30", ...]
var numbers = [1, 2, 3, 4]
numbers.shuffleInPlace()
// [3, 2, 1, 4]
(langue obsolète: vous ne pouvez pas utiliser Swift 1.x pour publier sur iTunes Connect à partir de juillet 2018)
shuffle
en tant que méthode de matrice en mutationCette extension vous permettra de mélanger une instance mutable Array
en place:
extension Array {
mutating func shuffle() {
if count < 2 { return }
for i in 0..<(count - 1) {
let j = Int(arc4random_uniform(UInt32(count - i))) + i
swap(&self[i], &self[j])
}
}
}
var numbers = [1, 2, 3, 4, 5, 6, 7, 8]
numbers.shuffle() // e.g., numbers == [6, 1, 8, 3, 2, 4, 7, 5]
shuffled
en tant que méthode de tableau non mutantCette extension vous permettra de récupérer une copie mélangée d'une instance Array
:
extension Array {
func shuffled() -> [T] {
if count < 2 { return self }
var list = self
for i in 0..<(list.count - 1) {
let j = Int(arc4random_uniform(UInt32(list.count - i))) + i
swap(&list[i], &list[j])
}
return list
}
}
let numbers = [1, 2, 3, 4, 5, 6, 7, 8]
let mixedup = numbers.shuffled() // e.g., mixedup == [6, 1, 8, 3, 2, 4, 7, 5]
Edit: Comme indiqué dans d'autres réponses, Swift 4.2 finalement ajoute la génération de nombres aléatoires à la bibliothèque standard. , complet avec le brassage de tableaux.
Cependant, la suite GKRandom
/GKRandomDistribution
de GameplayKit peut toujours être utile avec le nouveau protocole RandomNumberGenerator
- si vous ajoutez des extensions au RNG de GameplayKit pour se conformer au nouveau protocole de bibliothèque standard, vous pouvez facilement obtenir:
... et utilisez toujours les nouvelles API aléatoires "natives" de Nice dans Swift.
Le reste de cette réponse concerne de tels RNG et/ou leur utilisation dans les anciens compilateurs Swift.
Il y a déjà de bonnes réponses ici, ainsi que de bonnes illustrations montrant pourquoi la rédaction de votre propre mélange peut être sujette aux erreurs si vous ne faites pas attention.
Dans iOS 9, macOS 10.11 et tvOS 9 (ou ultérieur), vous n'avez pas à écrire le vôtre. Il y a ne implémentation efficace et correcte de Fisher-Yates dans GameplayKit (qui, malgré son nom, ne concerne pas que les jeux).
Si vous voulez juste un mélange unique:
let shuffled = GKRandomSource.sharedRandom().arrayByShufflingObjects(in: array)
Si vous voulez pouvoir reproduire un mélange ou une série de mélanges, choisissez et ensemencez une source aléatoire spécifique; par exemple.
let lcg = GKLinearCongruentialRandomSource(seed: mySeedValue)
let shuffled = lcg.arrayByShufflingObjects(in: array)
Dans iOS 10/macOS 10.12/tvOS 10, il existe également une syntaxe pratique pour la lecture aléatoire via une extension sur NSArray
. Bien sûr, c'est un peu fastidieux lorsque vous utilisez un Swift Array
(et il perd son type d'élément lorsqu'il revient à Swift):
let shuffled1 = (array as NSArray).shuffled(using: random) // -> [Any]
let shuffled2 = (array as NSArray).shuffled() // use default random source
Mais il est assez facile de créer un wrapper Swift préservant le type:
extension Array {
func shuffled(using source: GKRandomSource) -> [Element] {
return (self as NSArray).shuffled(using: source) as! [Element]
}
func shuffled() -> [Element] {
return (self as NSArray).shuffled() as! [Element]
}
}
let shuffled3 = array.shuffled(using: random)
let shuffled4 = array.shuffled()
Dans Swift 2., GameplayKit pourrait venir à la rescousse! (pris en charge par iOS9 ou ultérieur)
import GameplayKit
func shuffle() {
array = GKRandomSource.sharedRandom().arrayByShufflingObjectsInArray(array)
}
Voici quelque chose peut-être un peu plus court:
sorted(a) {_, _ in arc4random() % 2 == 0}
Prenant l'algorithme de Nate je voulais voir à quoi ressemblerait cela avec Swift 2 et les extensions de protocole.
C'est ce que je suis venu avec.
extension MutableCollectionType where Self.Index == Int {
mutating func shuffleInPlace() {
let c = self.count
for i in 0..<(c - 1) {
let j = Int(arc4random_uniform(UInt32(c - i))) + i
swap(&self[i], &self[j])
}
}
}
extension MutableCollectionType where Self.Index == Int {
func shuffle() -> Self {
var r = self
let c = self.count
for i in 0..<(c - 1) {
let j = Int(arc4random_uniform(UInt32(c - i))) + i
swap(&r[i], &r[j])
}
return r
}
}
Maintenant, n'importe quel MutableCollectionType
peut utiliser ces méthodes étant donné qu'il utilise Int
comme un Index
Dans mon cas, j'ai eu quelques problèmes pour échanger des objets dans Array. Ensuite, je me suis gratté la tête et je suis parti pour réinventer la roue.
// Swift 3.0 ready
extension Array {
func shuffled() -> [Element] {
var results = [Element]()
var indexes = (0 ..< count).map { $0 }
while indexes.count > 0 {
let indexOfIndexes = Int(arc4random_uniform(UInt32(indexes.count)))
let index = indexes[indexOfIndexes]
results.append(self[index])
indexes.remove(at: indexOfIndexes)
}
return results
}
}
Ceci est une version de implémentation par Nate du shuffle de Fisher-Yates pour Swift 4 (Xcode 9).
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)
}
}
}
extension Collection {
/// Return a copy of `self` with its elements shuffled
func shuffled() -> [Element] {
var list = Array(self)
list.shuffle()
return list
}
}
Les changements sont les suivants:
Indices.Iterator.Element == Index
fait maintenant partie du protocole Collection
et ne doit plus être imposée à l'extension.swapAt()
sur la collection, comparez SE-0173 Add MutableCollection.swapAt(_:_:)
.Element
est un alias pour Iterator.Element
.C'est ce que j'utilise:
func newShuffledArray(array:NSArray) -> NSArray {
var mutableArray = array.mutableCopy() as! NSMutableArray
var count = mutableArray.count
if count>1 {
for var i=count-1;i>0;--i{
mutableArray.exchangeObjectAtIndex(i, withObjectAtIndex: Int(arc4random_uniform(UInt32(i+1))))
}
}
return mutableArray as NSArray
}
Swift 4 Mélanger les éléments d'un tableau dans une boucle for où i est le rapport de mélange
var cards = [Int]() //Some Array
let i = 4 // is the mixing ratio
func shuffleCards() {
for _ in 0 ..< cards.count * i {
let card = cards.remove(at: Int(arc4random_uniform(UInt32(cards.count))))
cards.insert(card, at: Int(arc4random_uniform(UInt32(cards.count))))
}
}
Ou avec extension Int
func shuffleCards() {
for _ in 0 ..< cards.count * i {
let card = cards.remove(at: cards.count.arc4random)
cards.insert(card, at: cards.count.arc4random)
}
}
extension Int {
var arc4random: Int {
if self > 0 {
print("Arc for random positiv self \(Int(arc4random_uniform(UInt32(self))))")
return Int(arc4random_uniform(UInt32(self)))
} else if self < 0 {
print("Arc for random negotiv self \(-Int(arc4random_uniform(UInt32(abs(self)))))")
return -Int(arc4random_uniform(UInt32(abs(self))))
} else {
print("Arc for random equal 0")
return 0
}
}
}
Solution Swift 3, après la réponse de @Nate Cook: (fonctionne si l'index commence par 0, voir les commentaires ci-dessous)
extension Collection {
/// Return a copy of `self` with its elements shuffled
func shuffle() -> [Generator.Element] {
var list = Array(self)
list.shuffleInPlace()
return list
} }
extension MutableCollection where Index == Int {
/// Shuffle the elements of `self` in-place.
mutating func shuffleInPlace() {
// empty and single-element collections don't shuffle
if count < 2 { return }
let countInt = count as! Int
for i in 0..<countInt - 1 {
let j = Int(arc4random_uniform(UInt32(countInt - i))) + i
guard i != j else { continue }
swap(&self[i], &self[j])
}
}
}
Voici comment cela se fait de la manière la plus simple .import Gamplaykit
à votre VC et utilisez le code ci-dessous. Testé dans Xcode 8.
import GameplayKit
let array: NSArray = ["Jock", "Ellie", "Sue Ellen", "Bobby", "JR", "Pamela"]
override func viewDidLoad() {
super.viewDidLoad()
print(array.shuffled())
}
Si vous voulez obtenir une chaîne mélangée d'un tableau, vous pouvez utiliser le code ci-dessous.
func suffleString() {
let ShuffleArray = array.shuffled()
suffleString.text = ShuffleArray.first as? String
print(suffleString.text!)
}
Formez l’article de Fisher – Yates shuffle sur Wikipedia
a). Méthode crayon-papier:
func shuffle<T>(_ array:inout [T]){
var temp = [T]()
for _ in array{
/*Generating random number with length*/
let random = arc4random_uniform(UInt32(array.count))
/*Take the element from array*/
let elementTaken = array[Int(random)]
/*Append it to new tempArray*/
temp.append(elementTaken)
/*Remove the element from array*/
array.remove(at: Int(random))
}
/* array = tempArray*/
array = temp
}
b). Méthode moderne: (version de Durstenfeld)
func shuffle<T>(_ array:inout [T]){
var length = array.count
for _ in array{
/*Generating random number with length*/
let random = arc4random_uniform(UInt32(length))
/*Check before index of two elements not same*/
if length-1 != Int(random){
swap(&array[length-1], &array[Int(random)])
}
length -= 1
}
}
Extension:
a). Méthode crayon-papier:
extension Array{
mutating func shuffled(){
var temp = [Element]()
for _ in self{
/*Generating random number with length*/
let random = arc4random_uniform(UInt32(self.count))
/*Take the element from array*/
let elementTaken = self[Int(random)]
/*Append it to new tempArray*/
temp.append(elementTaken)
/*Remove the element from array*/
self.remove(at: Int(random))
}
/* array = tempArray*/
self = temp
}
}
b). Méthode moderne: (version de Durstenfeld)
extension Array{
mutating func shuffled(){
var length = self.count
for _ in self{
/*Generating random number with length*/
let random = arc4random_uniform(UInt32(length))
/*Check before index of two elements not same*/
if length-1 != Int(random){
/*Swaping elements, If same index then there is no swap*/
// swap(&self[length-1], &self[Int(random)]) -> Swift 3.0
self.swapAt(length-1, Int(random)) //-> Swift 4.0
}
length -= 1
}
}
}
Référence:
/* By using shuffle functions*/
var a = [1,2,3,4,5,6,7,8,9,10]
for _ in 1...10{
self.shuffle(&a)
/*For shuffled extension, a.shuffled()*/
print(a)
}
Remarque: Vous pouvez également utiliser un tableau vide.
Sortie:
[6, 2, 10, 5, 1, 8, 9, 4, 3, 7]
[7, 1, 9, 8, 2, 10, 5, 6, 4, 3]
[8, 9, 6, 10, 5, 2, 7, 4, 3, 1]
[10, 1, 7, 4, 8, 9, 3, 5, 2, 6]
[8, 1, 6, 9, 3, 7, 4, 5, 10, 2]
[4, 3, 7, 9, 1, 5, 8, 6, 10, 2]
[7, 3, 4, 9, 10, 1, 6, 5, 2, 8]
[3, 6, 2, 4, 5, 8, 9, 7, 1, 10]
[5, 1, 2, 10, 6, 9, 7, 3, 8, 4]
[7, 9, 3, 8, 2, 1, 5, 4, 6, 10]
S'il vous plaît, laissez-moi savoir si des questions, Autre version Swift seront vérifiées bientôt.
Avec Swift 3, si vous souhaitez mélanger un tableau à la place ou obtenir un nouveau tableau mélangé dans un tableau, AnyIterator
peut vous aider. L'idée est de créer un tableau d'indices à partir de votre tableau, de mélanger ces index avec une instance AnyIterator
et une fonction swap(_:_:)
et de mapper chaque élément de cette instance AnyIterator
avec l'élément correspondant du tableau.
Le code de terrain de jeu suivant montre comment cela fonctionne:
import Darwin // required for arc4random_uniform
let array = ["Jock", "Ellie", "Sue Ellen", "Bobby", "JR", "Pamela"]
var indexArray = Array(array.indices)
var index = indexArray.endIndex
let indexIterator: AnyIterator<Int> = AnyIterator {
guard let nextIndex = indexArray.index(index, offsetBy: -1, limitedBy: indexArray.startIndex)
else { return nil }
index = nextIndex
let randomIndex = Int(arc4random_uniform(UInt32(index)))
if randomIndex != index {
swap(&indexArray[randomIndex], &indexArray[index])
}
return indexArray[index]
}
let newArray = indexIterator.map { array[$0] }
print(newArray) // may print: ["Jock", "Ellie", "Sue Ellen", "JR", "Pamela", "Bobby"]
Vous pouvez refactoriser le code précédent et créer une fonction shuffled()
à l'intérieur d'une extension Array
afin d'obtenir un nouveau tableau mélangé à partir d'un tableau:
import Darwin // required for arc4random_uniform
extension Array {
func shuffled() -> Array<Element> {
var indexArray = Array<Int>(indices)
var index = indexArray.endIndex
let indexIterator = AnyIterator<Int> {
guard let nextIndex = indexArray.index(index, offsetBy: -1, limitedBy: indexArray.startIndex)
else { return nil }
index = nextIndex
let randomIndex = Int(arc4random_uniform(UInt32(index)))
if randomIndex != index {
swap(&indexArray[randomIndex], &indexArray[index])
}
return indexArray[index]
}
return indexIterator.map { self[$0] }
}
}
Utilisation:
let array = ["Jock", "Ellie", "Sue Ellen", "Bobby", "JR", "Pamela"]
let newArray = array.shuffled()
print(newArray) // may print: ["Bobby", "Pamela", "Jock", "Ellie", "JR", "Sue Ellen"]
let emptyArray = [String]()
let newEmptyArray = emptyArray.shuffled()
print(newEmptyArray) // prints: []
Au lieu du code précédent, vous pouvez créer une fonction shuffle()
à l'intérieur d'une extension Array
afin de mélanger un tableau à la place:
import Darwin // required for arc4random_uniform
extension Array {
mutating func shuffle() {
var indexArray = Array<Int>(indices)
var index = indexArray.endIndex
let indexIterator = AnyIterator<Int> {
guard let nextIndex = indexArray.index(index, offsetBy: -1, limitedBy: indexArray.startIndex)
else { return nil }
index = nextIndex
let randomIndex = Int(arc4random_uniform(UInt32(index)))
if randomIndex != index {
swap(&indexArray[randomIndex], &indexArray[index])
}
return indexArray[index]
}
self = indexIterator.map { self[$0] }
}
}
Utilisation:
var mutatingArray = ["Jock", "Ellie", "Sue Ellen", "Bobby", "JR", "Pamela"]
mutatingArray.shuffle()
print(mutatingArray) // may print ["Sue Ellen", "Pamela", "Jock", "Ellie", "Bobby", "JR"]
Dans Swift 4.2 , il existe maintenant une méthode pour à la fois un mutable shuffle
et immuable shuffled
. Vous pouvez en savoir plus sur la génération aléatoire et les éléments de tableau ici .
Vous pouvez également utiliser la fonction générique swap
et implémenter les méthodes de Fisher-Yates mentionnées:
for idx in 0..<arr.count {
let rnd = Int(arc4random_uniform(UInt32(idx)))
if rnd != idx {
swap(&arr[idx], &arr[rnd])
}
}
ou moins verbeux:
for idx in 0..<steps.count {
swap(&steps[idx], &steps[Int(arc4random_uniform(UInt32(idx)))])
}
travaux!!. organismes est le tableau à mélanger.
extension Array
{
/** Randomizes the order of an array's elements. */
mutating func shuffle()
{
for _ in 0..<10
{
sort { (_,_) in arc4random() < arc4random() }
}
}
}
var organisms = [
"ant", "bacteria", "cougar",
"dog", "elephant", "firefly",
"goat", "hedgehog", "iguana"]
print("Original: \(organisms)")
organisms.shuffle()
print("Shuffled: \(organisms)")
La réponse la plus fréquente est obsolète. J'ai donc décidé de créer ma propre extension pour mélanger un tableau dans la dernière version de Swift, Swift 4.1 (Xcode 9):
extension Array {
// Non-mutating shuffle
var shuffled : Array {
let totalCount : Int = self.count
var shuffledArray : Array = []
var count : Int = totalCount
var tempArray : Array = self
for _ in 0..<totalCount {
let randomIndex : Int = Int(arc4random_uniform(UInt32(count)))
let randomElement : Element = tempArray.remove(at: randomIndex)
shuffledArray.append(randomElement)
count -= 1
}
return shuffledArray
}
// Mutating shuffle
mutating func shuffle() {
let totalCount : Int = self.count
var shuffledArray : Array = []
var count : Int = totalCount
var tempArray : Array = self
for _ in 0..<totalCount {
let randomIndex : Int = Int(arc4random_uniform(UInt32(count)))
let randomElement : Element = tempArray.remove(at: randomIndex)
shuffledArray.append(randomElement)
count -= 1
}
self = shuffledArray
}
}
[Array] -> [Array]
:let array = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
print(array.shuffled)
Ceci imprime array
dans un ordre aléatoire.
[Array] = [Array]
:var array = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
array.shuffle()
// The array has now been mutated and contains all of its initial
// values, but in a randomized shuffled order
print(array)
Ceci imprime array
dans son ordre actuel, qui a déjà été mélangé de manière aléatoire.
Espère que cela fonctionne pour tout le monde, si vous avez des questions, des suggestions ou des commentaires, n'hésitez pas à demander!
Si vous voulez utiliser simple Swift Pour la fonction de boucle, utilisez ceci ->
var arrayItems = ["A1", "B2", "C3", "D4", "E5", "F6", "G7", "H8", "X9", "Y10", "Z11"]
var shuffledArray = [String]()
for i in 0..<arrayItems.count
{
let randomObject = Int(arc4random_uniform(UInt32(items.count)))
shuffledArray.append(items[randomObject])
items.remove(at: randomObject)
}
print(shuffledArray)
Swift Array suffire en utilisant l'extension ->
extension Array {
// Order Randomize
mutating func shuffle() {
for _ in 0..<count {
sort { (_,_) in arc4random() < arc4random() }
}
}
}
Dans Swift 4
func createShuffledSequenceOfNumbers(max:UInt)->[UInt] {
var array:[UInt]! = []
var myArray:[UInt]! = []
for i in 1...max {
myArray.append(i)
}
for i in 1...max {
array.append(i)
}
var tempArray:[Int]! = []
for index in 0...(myArray.count - 1) {
var isNotFinded:Bool = true
while(isNotFinded){
let randomNumber = arc4random_uniform(UInt32(myArray.count))
let randomIndex = Int(randomNumber)
if(!tempArray.contains(randomIndex)){
tempArray.append(randomIndex)
array[randomIndex] = myArray[index]
isNotFinded = false
}
}
}
return array
}
Voici comment mélanger un tableau avec une graine dans Swift 3.0.
extension MutableCollection where Indices.Iterator.Element == Index {
mutating func shuffle() {
let c = count
guard c > 1 else { return }
for (firstUnshuffled , unshuffledCount) in Zip(indices, stride(from: c, to: 1, by: -1)) {
srand48(seedNumber)
let number:Int = numericCast(unshuffledCount)
let r = floor(drand48() * Double(number))
let d: IndexDistance = numericCast(Int(r))
guard d != 0 else { continue }
let i = index(firstUnshuffled, offsetBy: d)
swap(&self[firstUnshuffled], &self[i])
}
}
}
C'est ce que j'utilise:
import GameplayKit
extension Collection {
func shuffled() -> [Iterator.Element] {
let shuffledArray = (self as? NSArray)?.shuffled()
let outputArray = shuffledArray as? [Iterator.Element]
return outputArray ?? []
}
mutating func shuffle() {
if let selfShuffled = self.shuffled() as? Self {
self = selfShuffled
}
}
}
// Usage example:
var numbers = [1,2,3,4,5]
numbers.shuffle()
print(numbers) // output example: [2, 3, 5, 4, 1]
print([10, "hi", 9.0].shuffled()) // output example: [hi, 10, 9]
let shuffl = GKRandomSource.sharedRandom().arrayByShufflingObjects(in: arrayObject)
À partir de Swift 4.2, il existe deux fonctions pratiques:
// shuffles the array in place
myArray.shuffle()
et
// generates a new array with shuffled elements of the old array
let newArray = myArray.shuffled()
Exemple simple:
extension Array {
mutating func shuffled() {
for _ in self {
// generate random indexes that will be swapped
var (a, b) = (Int(arc4random_uniform(UInt32(self.count - 1))), Int(arc4random_uniform(UInt32(self.count - 1))))
if a == b { // if the same indexes are generated swap the first and last
a = 0
b = self.count - 1
}
swap(&self[a], &self[b])
}
}
}
var array = [1,2,3,4,5,6,7,8,9,10]
array.shuffled()
print(array) // [9, 8, 3, 5, 7, 6, 4, 2, 1, 10]