the programming para language descargar swift swift3

programming - Shuffle array swift 3



the swift programming language pdf (4)

Hay un shuffle de fisher-yates en Gamekit:

import GameKit let unshuffledArray = [1,2,3,4] let shuffledArray = GKRandomSource.sharedRandom().arrayByShufflingObjects(in: unshuffledArray) print(shuffledArray)

También puede pasar y almacenar una semilla aleatoria, de modo que obtenga la misma secuencia de valores aleatorios pseudoaleatorios cada vez que proporcione la misma semilla en caso de que necesite recrear una simulación.

import GameKit let unshuffledArray = [1,2,3,4] let randomSource = GKLinearCongruentialRandomSource(seed: 1) let shuffledArray = randomSource.arrayByShufflingObjects(in: unshuffledArray) //Always [1,4,2,3] print(shuffledArray)

¿Cómo puedo convertir la siguiente función a swift 3 ? Actualmente, obtener un Binary operator ''..<'' cannot be applied to operands of type ''Int'' and ''Self.IndexDistance'' error.

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 } for i in 0..<count - 1 { //error takes place here let j = Int(arc4random_uniform(UInt32(count - i))) + i guard i != j else { continue } swap(&self[i], &self[j]) } } }

referencia: https://stackoverflow.com/a/24029847/5222077


Puedes usar la Extensión NSArray del marco de GameplayKit para esto:

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]


Sugeriría simplemente barajar matrices en lugar de tratar de extender esto a las colecciones en general:

extension Array { mutating func shuffle () { for i in (0..<self.count).reversed() { let ix1 = i let ix2 = Int(arc4random_uniform(UInt32(i+1))) (self[ix1], self[ix2]) = (self[ix2], self[ix1]) } } }


count devuelve un IndexDistance que es el tipo que describe la distancia entre dos índices de recopilación. IndexDistance se requiere para ser un SignedInteger , pero no necesita ser un Int y puede ser diferente de Index . Por lo tanto, no es posible crear el rango 0..<count - 1 .

Una solución es usar startIndex y endIndex lugar de 0 y 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]) } } } }

Otra ventaja es que esto también funciona correctamente con cortes de matriz (donde el índice del primer elemento no es necesariamente cero).

Tenga en cuenta que de acuerdo con las nuevas "Directrices de diseño de API Swift" , shuffle() es el nombre "apropiado" para un método aleatorio mutante y shuffled() para la contraparte no mutante que devuelve una matriz:

extension Collection { /// Return a copy of `self` with its elements shuffled func shuffled() -> [Iterator.Element] { var list = Array(self) list.shuffle() return list } }

Actualización: se ha agregado una versión de Swift 3 (aún más general) a ¿Cómo barajo una matriz en Swift? mientras tanto.

Para Swift 4 (Xcode 9) uno tiene que reemplazar la llamada a la función swap() por una llamada al método swapAt() de la colección. Además, la restricción sobre el tipo de Index ya no es necesaria:

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) } } }

Consulte SE-0173 Agregar MutableCollection.swapAt(_:_:) para obtener más información sobre swapAt .

A partir de Swift 4.2 (Xcode 10, actualmente en versión beta), con la implementación de la Unificación aleatoria SE-0202 , shuffle() y shuffled() son parte de la biblioteca estándar de Swift.