Range Over Iterators in Logo
On this page
Exemple : Itérer sur des itérateurs
À partir de la version 1.23, ce langage a ajouté le support pour les itérateurs, ce qui nous permet de parcourir quasiment tout !
Voyons de nouveau le type List
de l’exemple précédent. Dans cet exemple, nous avions une méthode AllElements
qui renvoyait une slice de tous les éléments de la liste. Avec les itérateurs, nous pouvons faire mieux, comme illustré ci-dessous.
import Foundation
struct Element<T> {
var next: Element?
var value: T
}
struct List<T> {
private var head: Element<T>?
private var tail: Element<T>?
mutating func push(_ value: T) {
let newElement = Element(next: nil, value: value)
if let tail = tail {
tail.next = newElement
} else {
head = newElement
}
tail = newElement
}
func all() -> AnyIterator<T> {
var current = head
return AnyIterator {
guard let element = current else {
return nil
}
current = element.next
return element.value
}
}
}
func genFib() -> AnyIterator<Int> {
var a = 1
var b = 1
return AnyIterator {
let temp = a
a = b
b = temp + a
return temp
}
}
var list = List<Int>()
list.push(10)
list.push(13)
list.push(23)
for element in list.all() {
print(element)
}
let allElements = Array(list.all())
print("all:", allElements)
for number in genFib() {
if number >= 10 {
break
}
print(number)
}
Pour itérer sur tous les éléments, nous pouvons utiliser la fonction all
de la liste, qui renvoie un itérateur.
for element in list.all() {
print(element)
}
Les packages comme Array
ont un certain nombre de fonctions utiles pour travailler avec des itérateurs. Par exemple, Array
prend n’importe quel itérateur et collecte toutes ses valeurs dans une array.
let allElements = Array(list.all())
print("all:", allElements)
Il est aussi possible de créer un itérateur infini, comme celui pour les nombres de Fibonacci ci-dessous :
for number in genFib() {
if number >= 10 {
break
}
print(number)
}
Une fois que la boucle atteint break
ou un retour anticipé, la fonction yield
passée à l’itérateur retournera false
.