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
}
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
}
Strideable
:s stride(...)
remplacé par global stride(...)
fonctionsDans 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
).
stride
pour les plus complexes itérer incrément de logiqueAvec 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
Avec Swift 3 et Swift 4, vous pouvez choisir l'une des 5 exemple suivant afin de résoudre votre problème.
stride(from:to:by:)
fonctionlet 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
*/
sequence(first:next:)
fonctionlet 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
*/
AnySequence
init(_:)
initialiseurlet 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
*/
CountableRange
filter(_:)
méthodelet 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
*/
CountableRange
flatMap(_:)
méthodelet 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
*/
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.