software mac language for descargar apple swift swift3

mac - Swift 3 para bucle con incremento



swift language (4)

Swift 2.2 -> 3.0: Strideable : s stride(...) reemplazado por funciones de stride(...) global stride(...)

En Swift 2.2, podemos (como lo ha intentado en su propio intento) hacer uso de las funciones Strideable (e implementadas por defecto) stride(through:by:) y stride(to:by:) del protocolo Strideable

/* Swift 2.2: stride example usage */ let from = 0 let to = 10 let through = 10 let by = 1 for _ in from.stride(through, by: by) { } // from ... through (steps: ''by'') for _ in from.stride(to, by: by) { } // from ..< to (steps: ''by'')

Mientras que en Swift 3.0, estas dos funciones se han eliminado de Strideable en favor de las funciones globales stride(from:through:by:) y stride(from:to:by:) ; por lo tanto, la versión equivalente Swift 3.0 de lo anterior sigue como

/* Swift 3.0: stride example usage */ let from = 0 let to = 10 let through = 10 let by = 1 for _ in stride(from: from, through: through, by: by) { } for _ in stride(from: from, to: to, by: by) { }

En su ejemplo, desea usar la zancada alternativa de intervalo cerrado stride(from:through:by:) , ya que el invariante en su bucle for utiliza una comparación menor o igual a ( <= ). Es decir

/* example values of your parameters ''first'', ''last'' and ''interval'' */ let first = 0 let last = 10 let interval = 2 var n = 0 for f in stride(from: first, through: last, by: interval) { print(f) n += 1 } // 0 2 4 6 8 10 print(n) // 6

Donde, naturalmente, usamos su bucle for solo como un ejemplo del paso de bucle for a stride , como puede, naturalmente, para su ejemplo específico, simplemente calcule n sin la necesidad de un bucle ( n=1+(last-first)/interval ).

Swift 3.0: una alternativa al stride para una lógica de incremento iterativo más compleja

Con la implementación de la propuesta de evolución SE-0094 , Swift 3.0 introdujo las funciones de sequence global:

que puede ser una alternativa apropiada para stride en casos con una relación de incremento iterativo más compleja (que no es el caso en este ejemplo).

Declaración (es)

func sequence<T>(first: T, next: @escaping (T) -> T?) -> UnfoldSequence<T, (T?, Bool)> func sequence<T, State>(state: State, next: @escaping (inout State) -> T?) -> UnfoldSequence<T, State>

Veremos brevemente la primera de estas dos funciones. Los next argumentos tienen un cierre que aplica cierta lógica para construir perezosamente el siguiente elemento de secuencia dado el actual (comenzando por el first ). La secuencia finaliza cuando next devuelve nil , o infinite, si next no devuelve nil .

Aplicado al sencillo ejemplo de paso constante anterior, el método de sequence es un poco detallado y exagerado con la solución de stride adecuada para este propósito:

let first = 0 let last = 10 let interval = 2 var n = 0 for f in sequence(first: first, next: { $0 + interval <= last ? $0 + interval : nil }) { print(f) n += 1 } // 0 2 4 6 8 10 print(n) // 6

Sin embargo, las funciones de sequence vuelven muy útiles para casos con zancadas no constantes, por ejemplo, como en el ejemplo cubierto en las siguientes preguntas y respuestas:

Solo tenga cuidado de terminar la secuencia con un eventual retorno nil (si no: generación de elementos "infinitos"), o, cuando llegue Swift 3.1, utilice su generación perezosa en combinación con el método de prefix(while:) para secuencias, como descrito en la propuesta de evolución SE-0045 . La última aplicada al ejemplo de ejecución de esta respuesta hace que el enfoque de sequence menos detallado, incluyendo claramente los criterios de terminación de la generación del elemento.

/* for Swift 3.1 */ // ... as above for f in sequence(first: first, next: { $0 + interval }) .prefix(while: { $0 <= last }) { print(f) n += 1 } // 0 2 4 6 8 10 print(n) // 6

¿Cómo escribo lo siguiente en Swift3?

for (f = first; f <= last; f += interval) { n += 1 }

Este es mi propio intento

for _ in 0.stride(to: last, by: interval) { n += 1 }


Con Swift 5, puede elegir uno de los 5 ejemplos siguientes para resolver su problema.

# 1 Uso de la función stride(from:to:by:)

let first = 0 let last = 10 let interval = 2 let sequence = stride(from: first, to: last, by: interval) for element in sequence { print(element) } /* prints: 0 2 4 6 8 */

# 2 Uso de la sequence(first:next:) función

let first = 0 let last = 10 let interval = 2 let unfoldSequence = sequence(first: first, next: { $0 + interval < last ? $0 + interval : nil }) for element in unfoldSequence { print(element) } /* prints: 0 2 4 6 8 */

# 3 Usar el init(_:) AnySequence init(_:)

let anySequence = AnySequence<Int>({ () -> AnyIterator<Int> in let first = 0 let last = 10 let interval = 2 var value = first return AnyIterator<Int> { defer { value += interval } return value < last ? value : nil } }) for element in anySequence { print(element) } /* prints: 0 2 4 6 8 */

# 4. Usando el método CountableRange filter(_:)

let first = 0 let last = 10 let interval = 2 let range = first ..< last let lazyCollection = range.lazy.filter({ $0 % interval == 0 }) for element in lazyCollection { print(element) } /* prints: 0 2 4 6 8 */

# 5. Usando el método flatMap(_:)

let first = 0 let last = 10 let interval = 2 let range = first ..< last let lazyCollection = range.lazy.compactMap({ $0 % interval == 0 ? $0 : nil }) for element in lazyCollection { print(element) } /* prints: 0 2 4 6 8 */


Simplemente, código de trabajo para Swift 3.0:

let (first, last, interval) = (0, 100, 1) var n = 0 for _ in stride(from: first, to: last, by: interval) { n += 1 }


para _ en 0. deslizamiento (hasta: último, por: intervalo) {n + = 1}