51 votes

Swift 3 pour la boucle avec incrément de

Comment puis-je écrire ce qui suit dans Swift3?

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

C'est ma propre tentative

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

72voto

dfri Points 11222

Swift 2.2 -> 3.0: Strideable:s stride(...) remplacé par global stride(...) fonctions

Dans Swift 2.2, on peut (comme vous l'avez essayé dans votre propre tenter de) faire usage de la blueprinted (et par défaut-mise en œuvre des fonctions d' stride(through:by:) et stride(to:by:) le protocole 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')

Alors que dans Swift 3.0, ces deux fonctions a été retiré de l' Strideable en faveur de l'fonctions globales stride(from:through:by:) et stride(from:to:by:); par conséquent, l'équivalent Swift version 3.0 de la ci-dessus comme suit

/* 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) { }

Dans votre exemple, vous voulez utiliser l'intervalle fermé dans la foulée de rechange stride(from:through:by:), puisque l'invariant dans votre for boucle utilise la comparaison pour moins de ou égal à (<=). I. e.

/* 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

D'où, naturellement, nous utilisons votre for boucle comme un exemple du passage de l' for boucle d' stride, comme vous pouvez naturellement, pour votre exemple, il suffit de calculer n sans la nécessité d'une boucle (n=1+(last-first)/interval).

Swift 3.0: Une alternative à l' stride pour les plus complexes itérer incrément de logique

Avec la mise en œuvre de l'évolution de la proposition SE-0094, Swift 3.0 a introduit le global sequence fonctions de:

ce qui peut être une alternative appropriée à l' stride pour les cas plus complexes itérer incrément de la relation (qui n'est pas le cas dans cet exemple).

Déclaration(s)

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>

Nous allons examiner brièvement lors de la première de ces deux fonctions. L' next arguments prend une fermeture qui s'applique un peu de logique paresseusement construire prochain élément de la séquence étant donné le contexte actuel d'un (en commençant par first). La séquence est terminée quand next retours nil, ou infini, si un next ne retourne jamais nil.

Appliqué à la simple constante foulée exemple ci-dessus, l' sequence méthode est un peu verbeux et overkill w.r.t. l'ajustement-pour-cette-fin stride solution:

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

L' sequence fonctions très utiles pour les cas non constant foulée, cependant, par exemple, comme dans l'exemple couverts à la suite de Q&A:

Il suffit de prendre soin de mettre fin à la séquence avec un éventuel nil de retour (si ce n'est: "l'infini" de l'élément de génération), ou, lorsque Swift 3.1 arrive, faire usage de son paresseux de génération en combinaison avec l' prefix(while:) méthode pour les séquences, comme décrit dans l'évolution de la proposition SE-0045. Celle-ci s'applique à l'exemple de cette réponse fait l' sequence approche moins verbeux, clairement, y compris les critères d'interruption de l'élément de génération.

/* 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

39voto

Imanou Petit Points 43068

Avec Swift 3 et Swift 4, vous pouvez choisir l'une des 5 exemple suivant afin de résoudre votre problème.


#1. À l'aide de stride(from:to:by:) fonction

let first = 0
let last = 10
let interval = 2

let sequence = stride(from: first, to: last, by: interval)

for element in sequence {
    // do stuff
    print(element)
}

/*
prints:
0
2
4
6
8
*/

#2. À l'aide de sequence(first:next:) fonction

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 {
    // do stuff
    print(element)
}

/*
prints:
0
2
4
6
8
*/

#3. À l'aide de AnySequence init(_:) initialiseur

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 {
    // do stuff
    print(element)
}

/*
prints:
0
2
4
6
8
*/

#4. À l'aide de CountableRange filter(_:) méthode

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 {
    // do stuff
    print(element)
}

/*
prints:
0
2
4
6
8
*/

#5. À l'aide de CountableRange flatMap(_:) méthode

let first = 0
let last = 10
let interval = 2

let range = first ..< last
let lazyCollection = range.lazy.flatMap({ $0 % interval == 0 ? $0 : nil })

for element in lazyCollection {
    // do stuff
    print(element)
}

/*
prints:
0
2
4
6
8
*/

15voto

Yar Points 25421

Simplement, le code du travail pour Swift 3.0:

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

-5voto

user462990 Points 851

pour _ 0.foulée(à l': dernier, par: intervalle) { n += 1 }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X