Lorsque j'utilise la boucle for dans Playground, tout fonctionnait bien, jusqu'à ce que je change le premier paramètre de la boucle for pour qu'il soit la valeur la plus élevée. (itéré dans l'ordre décroissant)
Est-ce un bug? Quelqu'un d'autre l'avait-il?
for index in 510..509
{
var a = 10
}
Le compteur qui affiche le nombre d'itérations qui seront des exécutions continue de cocher ...
ios
swift
swift-playground
Krishnan
la source
la source
Réponses:
Xcode 6 beta 4 a ajouté deux fonctions pour itérer sur des plages avec une étape autre que une:,
stride(from: to: by:)
qui est utilisée avec des plages exclusives etstride(from: through: by:)
, qui est utilisée avec des plages inclusives.Pour itérer sur une plage dans l'ordre inverse, ils peuvent être utilisés comme ci-dessous:
Notez qu'aucun de ceux-ci n'est une
Range
fonction membre. Ce sont des fonctions globales qui renvoient soit a,StrideTo
soit uneStrideThrough
structure, qui sont définies différemment de laRange
structure.Une version précédente de cette réponse utilisait la
by()
fonction membre de laRange
structure, qui a été supprimée dans la version bêta 4. Si vous voulez voir comment cela fonctionnait, vérifiez l'historique des modifications.la source
5.stride(to: 1, by: -1)
ou5.stride(through: 1, by: -1)
:
opérateur itérant implicitement vers le bas, provoquant l'exécution de leurs boucles alors qu'ils pensaient qu'il les ignorerait. C'est très pratique pour une utilisation interactive, mais terriblement sujet aux erreurs dans les scripts, au point où les guides de style déconseillent de l'utiliser .Appliquez la fonction inverse à la plage pour itérer vers l'arrière:
Pour Swift 1.2 et versions antérieures:
Il fonctionne également avec des plages semi-ouvertes:
Remarque:
reverse(1...10)
crée un tableau de type[Int]
, donc bien que cela puisse convenir pour les petites plages, il serait sage de l'utiliserlazy
comme indiqué ci-dessous ou de considérer lastride
réponse acceptée si votre plage est grande.Pour éviter de créer un grand tableau, utilisez
lazy
avecreverse()
. Le test suivant s'exécute efficacement dans un Playground montrant qu'il ne crée pas un tableau avec un billion deInt
s!Tester:
Pour Swift 2.0 dans Xcode 7:
Notez que dans Swift 2.0,
(1...1_000_000_000_000).reverse()
est de typeReverseRandomAccessCollection<(Range<Int>)>
, donc cela fonctionne bien:Pour Swift 3.0
reverse()
a été renommé enreversed()
:la source
reversed
peut copier la collection, cependant. Au moins, c'est ainsi que je comprends la documentation surData
.Mis à jour pour Swift 3
La réponse ci-dessous est un résumé des options disponibles. Choisissez celui qui correspond le mieux à vos besoins.
reversed
: nombres dans une plageVers l'avant
En arrière
reversed
: éléments dansSequenceType
Vers l'avant
En arrière
reversed
: éléments avec un indexParfois, un index est nécessaire lors de l'itération dans une collection. Pour cela, vous pouvez utiliser
enumerate()
, qui renvoie un tuple. Le premier élément du tuple est l'index et le deuxième élément est l'objet.Vers l'avant
En arrière
Notez que comme Ben Lachman l'a noté dans sa réponse , vous voulez probablement faire
.enumerated().reversed()
plutôt que.reversed().enumerated()
(ce qui ferait augmenter les indices).foulée: chiffres
Stride est un moyen d'itérer sans utiliser de plage. Il existe deux formes. Les commentaires à la fin du code montrent ce que serait la version de la plage (en supposant que la taille d'incrémentation est de 1).
Vers l'avant
En arrière
Changer la taille d'incrément en
-1
vous permet de revenir en arrière.Notez la différence
to
etthrough
.stride: éléments de SequenceType
Avancer par incréments de 2
J'utilise
2
dans cet exemple juste pour montrer une autre possibilité.En arrière
Remarques
@matt a une solution intéressante où il définit son propre opérateur inverse et l'appelle
>>>
. Cela ne prend pas beaucoup de code à définir et est utilisé comme ceci:Découvrez le style C pour les boucles supprimées de Swift 3
la source
Swift 4 et plus
la source
Avec Swift 5, selon vos besoins, vous pouvez choisir l'un des quatre exemples de code Playground suivants afin de résoudre votre problème.
#1. Utilisation de la
ClosedRange
reversed()
méthodeClosedRange
a une méthode appeléereversed()
.reversed()
method a la déclaration suivante:Usage:
Comme alternative, vous pouvez utiliser la
Range
reversed()
méthode:# 2. Utilisation de la
sequence(first:next:)
fonctionLa bibliothèque standard Swift fournit une fonction appelée
sequence(first:next:)
.sequence(first:next:)
a la déclaration suivante:Usage:
# 3. Utilisation de la
stride(from:through:by:)
fonctionLa bibliothèque standard Swift fournit une fonction appelée
stride(from:through:by:)
.stride(from:through:by:)
a la déclaration suivante:Usage:
Comme alternative, vous pouvez utiliser
stride(from:to:by:)
:# 4. Utilisation de l'
AnyIterator
init(_:)
initialiseurAnyIterator
a un initialiseur appeléinit(_:)
.init(_:)
a la déclaration suivante:Usage:
Si nécessaire, vous pouvez refactoriser le code précédent en créant une méthode d'extension pour
Int
et en y enveloppant votre itérateur:la source
Pour Swift 2.0 et supérieur, vous devez appliquer l'inverse sur une collection de plage
Il a été renommé en .reversed () dans Swift 3.0
la source
Dans Swift 4 et les derniers
la source
Swift 4.0
Si vous souhaitez inclure la
to
valeur:la source
Si l'on veut parcourir un tableau (
Array
ou plus généralement n'importe lequelSequenceType
) en sens inverse. Vous avez quelques options supplémentaires.Vous pouvez d'abord
reverse()
le tableau et le parcourir en boucle comme d'habitude. Cependant, je préfère utiliser laenumerate()
plupart du temps car il génère un tuple contenant l'objet et son index.La seule chose à noter ici est qu'il est important de les appeler dans le bon ordre:
for (index, element) in array.enumerate().reverse()
donne des index dans l'ordre décroissant (ce que j'attends généralement). tandis que:
for (index, element) in array.reverse().enumerate()
(qui est une correspondance plus proche de NSArrayreverseEnumerator
)parcourt le tableau en arrière mais génère des index ascendants.
la source
comme pour Swift 2.2, Xcode 7.3 (10, juin 2016):
Production :
la source
Vous pouvez envisager d'utiliser la
while
boucle C-Style à la place. Cela fonctionne très bien dans Swift 3:la source
Vous pouvez utiliser la méthode reverse () pour inverser facilement les valeurs.
La méthode reverse () inverse les valeurs.
la source
la source