Lorsque j'utilise la boucle for dans Playground, tout a bien fonctionné, jusqu'à ce que le premier paramètre de boucle soit remplacé par la valeur la plus élevée. (itéré en 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 ...
Xcode 6 beta 4 a ajouté deux fonctions pour parcourir les plages avec une étape autre que la suivante: stride(from: to: by:)
, utilisée avec les plages exclusives, et stride(from: through: by:)
, utilisée avec les plages incluses.
Pour itérer sur une plage dans l'ordre inverse, ils peuvent être utilisés comme suit:
for index in stride(from: 5, to: 1, by: -1) {
print(index)
}
//prints 5, 4, 3, 2
for index in stride(from: 5, through: 1, by: -1) {
print(index)
}
//prints 5, 4, 3, 2, 1
Notez que ni l'une ni l'autre de ces fonctions n'est une fonction membre Range
. Ce sont des fonctions globales qui retournent une structure StrideTo
ou StrideThrough
, définies différemment de la structure Range
.
Une version précédente de cette réponse utilisait la fonction membre by()
de la structure Range
, qui avait été supprimée à la version bêta 4. Si vous voulez voir comment cela fonctionne, consultez l'historique d'édition.
Appliquez la fonction reverse à la plage pour effectuer une itération inverse:
Pour Swift 1.2 et antérieur:
// Print 10 through 1
for i in reverse(1...10) {
println(i)
}
Cela fonctionne également avec les gammes semi-ouvertes:
// Print 9 through 1
for i in reverse(1..<10) {
println(i)
}
Remarque: reverse(1...10)
crée un tableau de type [Int]
. Par conséquent, bien que cela puisse convenir pour de petites plages, il serait judicieux d'utiliser lazy
comme indiqué ci-dessous ou de considérer la réponse acceptée stride
si votre plage est grande.
Pour éviter de créer un tableau de grande taille, utilisez lazy
avec reverse()
. Le test suivant fonctionne efficacement dans une aire de jeu et montre qu'il ne crée pas de tableau avec un billion de Int
s!
Test:
var count = 0
for i in lazy(1...1_000_000_000_000).reverse() {
if ++count > 5 {
break
}
println(i)
}
Pour Swift 2. dans Xcode 7:
for i in (1...10).reverse() {
print(i)
}
Notez que dans Swift 2.0, (1...1_000_000_000_000).reverse()
est de type ReverseRandomAccessCollection<(Range<Int>)>
, donc cela fonctionne bien:
var count = 0
for i in (1...1_000_000_000_000).reverse() {
count += 1
if count > 5 {
break
}
print(i)
}
Pour Swift 3.reverse()
a été renommé en reversed()
:
for i in (1...10).reversed() {
print(i) // prints 10 through 1
}
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 plageTransférer
for index in 0..<5 {
print(index)
}
// 0
// 1
// 2
// 3
// 4
en arrière
for index in (0..<5).reversed() {
print(index)
}
// 4
// 3
// 2
// 1
// 0
reversed
: éléments dans SequenceType
let animals = ["horse", "cow", "camel", "sheep", "goat"]
Transférer
for animal in animals {
print(animal)
}
// horse
// cow
// camel
// sheep
// goat
en arrière
for animal in animals.reversed() {
print(animal)
}
// goat
// sheep
// camel
// cow
// horse
reversed
: éléments avec un indexParfois, un index est nécessaire lors d'une itération dans une collection. Pour cela, vous pouvez utiliser enumerate()
, qui retourne un tuple. Le premier élément du tuple est l'index et le second élément est l'objet.
let animals = ["horse", "cow", "camel", "sheep", "goat"]
Transférer
for (index, animal) in animals.enumerated() {
print("\(index), \(animal)")
}
// 0, horse
// 1, cow
// 2, camel
// 3, sheep
// 4, goat
en arrière
for (index, animal) in animals.enumerated().reversed() {
print("\(index), \(animal)")
}
// 4, goat
// 3, sheep
// 2, camel
// 1, cow
// 0, horse
Notez que, comme Ben Lachman l’a noté dans sa réponse , vous voudrez probablement faire .enumerated().reversed()
plutôt que .reversed().enumerated()
(ce qui augmenterait le nombre d’index).
Stride est un moyen d'itérer sans utiliser de plage. Il y a deux formes. Les commentaires à la fin du code indiquent quelle serait la version de la plage (en supposant que la taille de l'incrément est 1).
startIndex.stride(to: endIndex, by: incrementSize) // startIndex..<endIndex
startIndex.stride(through: endIndex, by: incrementSize) // startIndex...endIndex
Transférer
for index in stride(from: 0, to: 5, by: 1) {
print(index)
}
// 0
// 1
// 2
// 3
// 4
en arrière
Changer la taille de l'incrément en -1
vous permet de revenir en arrière.
for index in stride(from: 4, through: 0, by: -1) {
print(index)
}
// 4
// 3
// 2
// 1
// 0
Notez la différence to
et through
.
Avancer par incréments de 2
let animals = ["horse", "cow", "camel", "sheep", "goat"]
J'utilise 2
dans cet exemple pour montrer une autre possibilité.
for index in stride(from: 0, to: 5, by: 2) {
print("\(index), \(animals[index])")
}
// 0, horse
// 2, camel
// 4, goat
en arrière
for index in stride(from: 4, through: 0, by: -1) {
print("\(index), \(animals[index])")
}
// 4, goat
// 3, sheep
// 2, camel
// 1, cow
// 0, horse
@matt a ne 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:
for index in 5>>>0 {
print(index)
}
// 4
// 3
// 2
// 1
// 0
Check out sur les boucles de style C for supprimées de Swift
Swift 4 à partir de
for i in stride(from: 5, to: 0, by: -1) {
print(i)
}
//prints 5, 4, 3, 2, 1
for i in stride(from: 5, through: 0, by: -1) {
print(i)
}
//prints 5, 4, 3, 2, 1, 0
Pour Swift 2.0 et versions ultérieures, vous devez appliquer l'inverse sur une collection de plages.
for i in (0 ..< 10).reverse() {
// process
}
Il a été renommé en .reversed () dans Swift 3.0
Avec Swift 5, en fonction de vos besoins, vous pouvez choisir l’un des quatre exemples de code suivants: afin de résoudre votre problème. .
ClosedRange
reversed()
ClosedRange
a une méthode appelée reversed()
. La méthode reversed()
a la déclaration suivante:
func reversed() -> ReversedCollection<ClosedRange<Bound>>
Renvoie une vue présentant les éléments de la collection dans l'ordre inverse.
Utilisation:
let reversedCollection = (0 ... 5).reversed()
for index in reversedCollection {
print(index)
}
/*
Prints:
5
4
3
2
1
0
*/
Vous pouvez également utiliser la méthode Range
reversed()
:
let reversedCollection = (0 ..< 6).reversed()
for index in reversedCollection {
print(index)
}
/*
Prints:
5
4
3
2
1
0
*/
sequence(first:next:)
Swift Standard Library fournit une fonction appelée sequence(first:next:)
. sequence(first:next:)
a la déclaration suivante:
func sequence<T>(first: T, next: @escaping (T) -> T?) -> UnfoldFirstSequence<T>
Retourne une séquence formée à partir de
first
et d'applications répétées denext
.
Utilisation:
let unfoldSequence = sequence(first: 5, next: {
$0 > 0 ? $0 - 1 : nil
})
for index in unfoldSequence {
print(index)
}
/*
Prints:
5
4
3
2
1
0
*/
stride(from:through:by:)
Swift Standard Library fournit une fonction appelée stride(from:through:by:)
. stride(from:through:by:)
a la déclaration suivante:
func stride<T>(from start: T, through end: T, by stride: T.Stride) -> StrideThrough<T> where T : Strideable
Renvoie une séquence d'une valeur initiale vers et éventuellement une valeur finale, en progressant de la valeur spécifiée.
Utilisation:
let sequence = stride(from: 5, through: 0, by: -1)
for index in sequence {
print(index)
}
/*
Prints:
5
4
3
2
1
0
*/
Comme alternative, vous pouvez utiliser stride(from:to:by:)
:
let sequence = stride(from: 5, to: -1, by: -1)
for index in sequence {
print(index)
}
/*
Prints:
5
4
3
2
1
0
*/
AnyIterator
init(_:)
initializerAnyIterator
a un initialiseur appelé init(_:)
. init(_:)
a la déclaration suivante:
init(_ body: @escaping () -> AnyIterator<Element>.Element?)
Crée un itérateur qui enveloppe la fermeture donnée dans sa méthode
next()
.
Utilisation:
var index = 5
guard index >= 0 else { fatalError("index must be positive or equal to zero") }
let iterator = AnyIterator({ () -> Int? in
defer { index = index - 1 }
return index >= 0 ? index : nil
})
for index in iterator {
print(index)
}
/*
Prints:
5
4
3
2
1
0
*/
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:
extension Int {
func iterateDownTo(_ endIndex: Int) -> AnyIterator<Int> {
var index = self
guard index >= endIndex else { fatalError("self must be greater than or equal to endIndex") }
let iterator = AnyIterator { () -> Int? in
defer { index = index - 1 }
return index >= endIndex ? index : nil
}
return iterator
}
}
let iterator = 5.iterateDownTo(0)
for index in iterator {
print(index)
}
/*
Prints:
5
4
3
2
1
0
*/
Dans Swift 4 et cette dernière
let count = 50//For example
for i in (1...count).reversed() {
print(i)
}
Swift 4.
for i in stride(from: 5, to: 0, by: -1) {
print(i) // 5,4,3,2,1
}
Si vous souhaitez inclure la valeur to
:
for i in stride(from: 5, through: 0, by: -1) {
print(i) // 5,4,3,2,1,0
}
Si l'on veut parcourir un tablea (Array
ou plus généralement n'importe quel SequenceType
) à l'envers. Vous avez quelques options supplémentaires.
Tout d’abord, vous pouvez reverse()
le tableau et le parcourir normalement. Cependant, je préfère utiliser enumerate()
la plupart du temps, car il génère un tuple contenant l'objet et son index.
Une chose à noter ici est qu’il est important de les appeler dans le bon ordre:
for (index, element) in array.enumerate().reverse()
donne des indices en ordre décroissant (ce à quoi je m'attends généralement). tandis que:
for (index, element) in array.reverse().enumerate()
(ce qui correspond plus étroitement à reverseEnumerator
de NSArray)
fait reculer le tableau mais génère des index ascendants.
comme pour Swift 2.2, Xcode 7.3 (10, juin 2016):
for (index,number) in (0...10).enumerate() {
print("index \(index) , number \(number)")
}
for (index,number) in (0...10).reverse().enumerate() {
print("index \(index) , number \(number)")
}
Sortie:
index 0 , number 0
index 1 , number 1
index 2 , number 2
index 3 , number 3
index 4 , number 4
index 5 , number 5
index 6 , number 6
index 7 , number 7
index 8 , number 8
index 9 , number 9
index 10 , number 10
index 0 , number 10
index 1 , number 9
index 2 , number 8
index 3 , number 7
index 4 , number 6
index 5 , number 5
index 6 , number 4
index 7 , number 3
index 8 , number 2
index 9 , number 1
index 10 , number 0
Vous pouvez également utiliser la boucle C-Style while
. Cela fonctionne très bien dans Swift 3:
var i = 5
while i > 0 {
print(i)
i -= 1
}
Vous pouvez utiliser la méthode reverse () pour inverser facilement les valeurs.
var i:Int
for i in 1..10.reversed() {
print(i)
}
La méthode reverse () inverse les valeurs.
var sum1 = 0
for i in 0...100{
sum1 += i
}
print (sum1)
for i in (10...100).reverse(){
sum1 /= i
}
print(sum1)
Pour cela, vous pouvez utiliser la boucle while
qui est très facile
var i = 10
while i > 1{
print(i)
i = i - 1
}
Mais quand même, si vous voulez utiliser la boucle for, utilisez la méthode reversed()
for i in (1...10).reversed(){
print(i)
}