Comment est-ce que je mélange Un tableau dans Swift?

Comment puis-je randomiser ou mélanger les éléments dans un tableau dans Swift? Par exemple, si mon tableau se compose de 52 cartes à jouer, je veux shuffle le tableau afin de mélanger le deck.

263
demandé sur Cœur 2014-06-04 03:15:08

25 réponses

cette réponse détaille 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. Le nom et le comportement de chaque version Swift correspondent aux méthodes de tri mutant et non mutant pour cette version.

Swift 4.2+

shuffle et shuffled sont des natifs 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]

Swift 4.0 et 4.1

ces extensions ajoutent une méthode shuffle() à toute collection mutable (tableaux et tampons mutables dangereux) 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 les exemples Swift 4.2 ci-dessus.


Swift 3

ces extensions ajoutent une méthode shuffle() à toute mutation collection et un shuffled() méthode d'une 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 les exemples Swift 4.2 ci-dessus.


Swift 2

(langage obsolète: vous ne pouvez pas utiliser Swift 2.x à 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
    }
}

Utilisation:

[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]

Swift 1.2

(langage obsolète: vous ne pouvez pas utiliser Swift 1.x à publier sur iTunes Connect à partir de juillet 2018)

shuffle comme une mutation de la matrice de la méthode

cette extension vous permettra de mélanger un mutable Array instance 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 non-mutation méthode de tableau

cette 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]
544
répondu Nate Cook 2018-06-07 05:49:33

Edit: Comme indiqué dans d'autres réponses, Swift 4.2 enfin , ajoute la génération de nombre aléatoire de la bibliothèque standard, complet avec tableau de brassage.

cependant, la suite GKRandom / GKRandomDistribution dans GameplayKit peut encore être utile avec le nouveau protocole RandomNumberGenerator - si vous ajoutez des extensions au Gameplaykit RNGs pour se conformer au nouveau protocole de bibliothèque standard, vous pouvez facilement obtenir:

  • RNGs durables (pouvant reproduire une séquence "aléatoire" lorsque cela est nécessaire pour les essais)
  • Rng que le sacrifice de la robustesse pour la vitesse
  • RNGs qui produisent des distributions non uniformes

...et utilisez toujours les nouveaux API aléatoires "natives" de Swift.

le reste de cette réponse concerne ces RNGs et/ou leur utilisation dans les compilateurs Swift plus anciens.


il y a déjà de bonnes réponses ici, ainsi que de bonnes illustrations de la raison pour laquelle écrire votre propre mélange peut être sujet à erreur si vous n'êtes pas prudent.

Dans iOS 9, macOS 10.11, et tvOS 9 (ou version ultérieure), vous n'avez pas à écrire votre propre. Il y a une implémentation efficace et correcte de Fisher-Yates dans GameplayKit (qui, malgré le nom, n'est pas seulement pour les jeux).

Si vous voulez juste a unique shuffle:

let shuffled = GKRandomSource.sharedRandom().arrayByShufflingObjects(in: array)

si vous voulez être en mesure de répliquer 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 y a aussi une syntaxe pratique pour mélanger via une extension sur NSArray . Bien sûr, c'est un peu encombrant quand vous utilisez un Swift Array (et qu'il perd son type d'élément en revenant à 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 faire un emballage Swift qui préserve les caractères:

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()
127
répondu rickster 2018-06-19 01:06:43

dans Swift 2.0 , GameplayKit peut venir à la rescousse! (pris en charge par iOS9 ou plus tard) 151960920"

import GameplayKit

func shuffle() {
    array = GKRandomSource.sharedRandom().arrayByShufflingObjectsInArray(array)
}
29
répondu bluenowhere 2016-03-17 05:53:12

voici quelque chose d'un peu plus court:

sorted(a) {_, _ in arc4random() % 2 == 0}
26
répondu Jean Le Moignan 2014-11-06 02:46:19

prendre algorithme de Nate je voulais voir à quoi cela ressemblerait avec Swift 2 et les extensions de protocole.

C'est ce que j'ai inventé.

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

7
répondu Chris Wagner 2017-05-23 11:47:32

dans mon cas, j'ai eu quelques problèmes d'échange d'objets en tableau. Puis je me suis égratigné la tête et j'ai voulu réinventer la roue.

// swift 3.0 ready
extension Array {

    func shuffled() -> [Element] {
        var results = [Element]()
        var indexes = (0 ..< count).map { "151900920" }
        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
    }

}
6
répondu Kaz Yoshikawa 2016-10-24 04:46:33

Ceci est une version de Nate mise en œuvre de l'shuffle de Fisher-Yates pour "1519100920 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:

  • la contrainte Indices.Iterator.Element == Index fait désormais partie de Collection et ne doivent pas nécessairement être imposées aux une extension de plus.
  • échanger des éléments doit se faire en appelant swapAt() sur la collection, comparer SE-0173 ajouter MutableCollection.swapAt(_:_:) .
  • Element est un alias pour Iterator.Element .
4
répondu Martin R 2018-03-26 09:32:04

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
}
3
répondu iliketopgun 2015-04-09 14:43:47

Swift 4 Mélangez les éléments d'un réseau dans une boucle pour laquelle 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
        }
    }
}
3
répondu Sergei 2018-01-03 09:22:32

solution Swift 3, à la suite de @Nate Cook réponse: (travailler si l'indice 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])
        }
    }
}
2
répondu Anson Yao 2016-09-17 05:00:59

C'est comme ça que ça se fait de la façon la plus simple. import Gamplaykit à votre CV et utilisez le code ci-dessous. Testé en 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 à partir 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!)

}
2
répondu Joe 2016-12-04 13:22:40

avec Swift 3, Si vous voulez mélanger un tableau en place ou obtenir un nouveau tableau mélangé à partir d'un tableau, AnyIterator je peux vous aider. L'idée est de créer un tableau d'indices à partir de votre tableau, de mélanger ces indices avec une instance AnyIterator et swap(_:_:) fonction et de mapper chaque élément de cette instance AnyIterator avec l'élément correspondant du tableau.


le 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["151900920"] }
print(newArray) // may print: ["Jock", "Ellie", "Sue Ellen", "JR", "Pamela", "Bobby"]

vous pouvez modifier 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["151910920"] }
    }

}

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: []

comme alternative au code précédent, vous pouvez créer une fonction shuffle() à l'intérieur d'une extension Array afin de mélanger un tableau en 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["151940920"] }
    }

}

Utilisation:

var mutatingArray = ["Jock", "Ellie", "Sue Ellen", "Bobby", "JR", "Pamela"]
mutatingArray.shuffle()
print(mutatingArray) // may print ["Sue Ellen", "Pamela", "Jock", "Ellie", "Bobby", "JR"]
2
répondu Imanou Petit 2017-02-27 10:50:00

la Forme de l'article de shuffle de Fisher–Yates sur Wikipedia

Swift 3.1, 4.0

). Méthode au crayon et au 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:

). Méthode au crayon et au 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)
}

Note: Vous pouvez utiliser le tableau vide également.

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]

merci de me faire savoir si vous avez des questions, les autres versions de Swift seront vérifiées prochainement.

2
répondu Rajamohan S 2017-11-16 04:55:43

vous pouvez également utiliser la fonction générique swap et implémenter les Fisher-Yates mentionnés:

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)))])
}
1
répondu Daniel Bauke 2014-10-03 11:30:04

ça marche!!. 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)")
1
répondu Vimal 2017-12-08 10:06:42

c'est 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])
        }
    }
}
0
répondu Tayo119 2016-12-15 09:41:43
let shuffl = GKRandomSource.sharedRandom().arrayByShufflingObjects(in: arrayObject)
0
répondu Rohit Sisodia 2017-06-05 10:14:11

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]
0
répondu Daniel Illescas 2017-06-24 20:45:01

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]
0
répondu Bobby 2017-07-02 17:34:45
"151970920 de Travail" Extension Tableau (la mutation et de la non-mutation)

Swift 4.1 /Xcode 9

la réponse du haut est dépréciée, donc j'ai pris sur moi de créer ma propre extension pour mélanger un tableau dans la plus récente 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
    }
}

Call Non-Mutant Shuffle [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.


Call Mutant Shuffle [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) 

cette gravure array dans son ordre actuel, qui a déjà été mélangée au hasard.


espérons que cela fonctionne pour tout le monde, si vous avez des questions, des suggestions ou des commentaires, n'hésitez pas à demander!

0
répondu Noah Wilder 2018-03-21 16:14:12

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
}
0
répondu ali khezri 2018-05-17 07:52:30

Dans "151930920 Swift" 4.2 , il y a maintenant une méthode pour à la fois un mutable shuffle et immuable shuffled . Vous pouvez lire plus au sujet de la génération aléatoire et la substance de tableau ici .

0
répondu leogdion 2018-06-07 05:31:38

si vous voulez utiliser la fonction Swift simple pour 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 Tableau suffle à l'aide d'extension ->

extension Array {
    // Order Randomize
    mutating func shuffle() {
        for _ in 0..<count {
            sort { (_,_) in arc4random() < arc4random() }
        }
    }
}
0
répondu Rahul Singha Roy 2018-06-27 10:48:13

voici un code qui court dans la Cour de récré. Vous n'aurez pas besoin d'importer Darwin dans un projet Xcode réel.

import darwin

var a = [1,2,3,4,5,6,7]

func shuffle<ItemType>(item1: ItemType, item2: ItemType) -> Bool {
    return drand48() > 0.5
}

sort(a, shuffle)

println(a)
-2
répondu Dan Hixon 2014-06-04 00:48:40

Il s'arrêter au "swap(&moi[i], &moi[j])" lorsque je mettre à jour xCode version 7.4 de la bêta.

erreur fatale: l'échange d'un emplacement avec lui-même n'est pas supporté

j'ai trouvé la raison que i = j (fonction de la partition d'échange explosé)

donc j'ajoute une condition comme ci-dessous

if (i != j){
    swap(&list[i], &list[j])
}

YA! C'est OK pour moi.

-3
répondu 米米米 2015-08-26 03:27:06