traducir inglés ingles español cómo como swift for-loop iteration swift3

swift - ingles - cómo se dice en inglés



Express para bucles en rápido con rango dinámico (2)

... o cómo puedo usar el índice dentro de la condición del bucle for

Hola gente Como nos quedamos sin estilo c para bucles en swift 3, parece que no puedo encontrar una manera de expresar un poco más complejo para bucles, así que tal vez puedan ayudarme.

Si tuviera que escribir esto

for(int i=5; num/i > 0; i*=5)

en Swift 3, ¿cómo haría eso?

El cierre por el que vine fue:

for i in stride(from: 5, through: num, by: 5) where num/i > 0

pero esto, por supuesto, iterará 5 trozos a la vez si estoy siendo: 5, 25, 125, etc.

¿Algunas ideas?

Gracias


Para completar: una alternativa al enfoque del bucle while es usar un AnyIterator :

let num = 1000 var i = 5 for i in AnyIterator<Int>({ return i <= num ? { defer { i *= 5 }; return i }() : nil }) { // note that we choose to shadow the external i variable name, // such that any access to i within this loop will only refer // to the loop local immutable variable i. print(i) // e.g. i += 1 not legal, i refers to a constant here! } /* 5 25 125 625 */

Este método tiene el mismo inconveniente que el ciclo while, ya que la variable i "externa" del ciclo persiste fuera y después del alcance del bloque de ciclo. Sin embargo, esta variable i externa no es la variable i que se puede acceder dentro del cuerpo del bucle, ya que dejamos que la variable del cuerpo del bucle i sombree la externa, lo que limita el acceso a i dentro del cuerpo a lo inmutable, temporal (alcance del bucle local) uno.


Uso de una función auxiliar (originalmente definida en Convertir un estilo C para bucle que usa división para el paso a Swift 3 )

public func sequence<T>(first: T, while condition: @escaping (T)-> Bool, next: @escaping (T) -> T) -> UnfoldSequence<T, T> { let nextState = { (state: inout T) -> T? in // Return `nil` if condition is no longer satisfied: guard condition(state) else { return nil } // Update current value _after_ returning from this call: defer { state = next(state) } // Return current value: return state } return sequence(state: first, next: nextState) }

puedes escribir el bucle como

let num = 1000 for i in sequence(first: 5, while: { num/$0 > 0 }, next: { $0 * 5 }) { print(i) }

Una solución más simple sería un ciclo while:

var i = 5 while num/i > 0 { print(i) i *= 5 }

pero la ventaja de la primera solución es que el alcance de la variable del bucle está limitado al cuerpo del bucle y que la variable del bucle es una constante.

Swift 3.1 proporcionará un método de prefix(while:) para secuencias , y luego la función auxiliar ya no es necesaria:

let num = 1000 for i in sequence(first: 5, next: { $0 * 5 }).prefix(while: { num/$0 > 0 }) { print(i) }

Todas las soluciones anteriores son "equivalentes" al bucle C dado. Sin embargo, todos pueden bloquearse si num está cerca de Int.max y los Int.max $0 * 5 . Si eso es un problema, entonces debe verificar si $0 * 5 encaja en el rango entero antes de hacer la multiplicación.

En realidad, eso hace que el ciclo sea más simple, al menos si suponemos que num >= 5 para que el ciclo se ejecute al menos una vez:

for i in sequence(first: 5, next: { $0 <= num/5 ? $0 * 5 : nil }) { print(i) }