Patron Itérateur
Fait partie de la section Programmation orientée objet du Journey R de Coddy. Leçon 49 sur 57.
Un itérateur fournit les éléments d’une collection un à un, de sorte que le code qui les utilise n’a pas besoin de savoir comment la collection est stockée. Une fermeture conserve la position : has_next() et next_value() constituent toute l’interface :
make_iterator <- function(x) {
i <- 0
list(
has_next = function() i < length(x),
next_value = function() {
i <<- i + 1
x[[i]]
}
)
}
it <- make_iterator(c("a", "b", "c"))
while (it$has_next()) cat(it$next_value(), "")Résultat :
a b c Un générateur est un itérateur qui calcule chaque valeur lorsqu’on la lui demande, de sorte que la séquence n’a pas besoin d’exister en mémoire. Il peut même être infini :
make_fib <- function() {
a <- 0
b <- 1
list(has_next = function() TRUE,
next_value = function() {
value <- a
nxt <- a + b
a <<- b
b <<- nxt
value
})
}
fib <- make_fib()
for (i in 1:10) cat(fib$next_value(), "")Sortie :
0 1 1 2 3 5 8 13 21 34 L’itérateur masque la disposition. Les résultats stockés dans des pages, dont certaines sont vides, apparaissent comme une seule séquence plate :
make_paged <- function(pages) {
p <- 1
i <- 0
skip_empty <- function() while (p <= length(pages) && i >= length(pages[[p]])) { p <<- p + 1; i <<- 0 }
list(
has_next = function() { skip_empty(); p <= length(pages) },
next_value = function() { skip_empty(); i <<- i + 1; pages[[p]][i] }
)
}
it <- make_paged(list(c("a", "b"), character(0), c("c")))
while (it$has_next()) cat(it$next_value(), "")Sortie :
a b c Les fonctions utilitaires écrites pour l’interface fonctionnent avec chaque itérateur. take(it, n) récupère jusqu’à n valeurs, depuis un vecteur, un générateur ou tout autre objet doté de has_next() et de next_value() :
make_iterator <- function(x) {
i <- 0
list(has_next = function() i < length(x), next_value = function() { i <<- i + 1; x[[i]] })
}
take <- function(it, n) {
out <- c()
while (length(out) < n && it$has_next()) out <- c(out, it$next_value())
out
}
it <- make_iterator(1:5)
print(take(it, 2))
print(take(it, 10))Sortie :
[1] 1 2
[1] 3 4 5Défi
FacileComplétez Iterator.R :
make_iterator(x): un itérateur sur les éléments d’un vecteur, avechas_next()etnext_value();make_range(from, to, by): un générateur defrom,from + by, ... jusqu’àtoinclus, calculés un à la fois ;take(it, n): au plusnvaleurs suivantes d’un itérateur quelconque.
Le code fourni lit des lignes range 1 10 3 take 2 5 (from, to, by, puis les tailles de chaque take) ou list a,b,c take 2 2, et affiche ce que chaque take() renvoie.
Votre code doit être placé dans Iterator.R. main.R contient le code fourni d’entrée/sortie et ne peut pas être modifié.
Essayez vous-même
source("Iterator.R")
# Code d'entrée/sortie fourni : le garder tel quel
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
p <- strsplit(line, " ")[[1]]
it <- if (p[1] == "range") make_range(as.numeric(p[2]), as.numeric(p[3]), as.numeric(p[4])) else make_iterator(strsplit(p[2], ",")[[1]])
k <- if (p[1] == "range") 5 else 3
for (n in as.numeric(p[-(1:k)])) {
got <- take(it, n)
cat("take ", n, ": ", if (length(got) == 0) "(nothing)" else paste(got, collapse = " "), "\n", sep = "")
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation orientée objet
1Bases de S3
Travailler avec les fichiersListes avec une classeFonctions constructricesMéthodes print et formatValidateurs et fonctions utilitairesRécapitulatif - Températures4Encapsulation dans R
Les fermetures comme objetsLes environnements comme objetsFonctions d’accèsProtéger l’étatRécapitulatif - Parcmètre2S3 : génériques et méthodes
Génériques et UseMethodMéthodes par défautMéthodes pour les génériques de baseNotions de base sur NextMethodRécapitulatif - Aires des formes5Classes S4
Définir des classes S4Slots et accèsVérifications de validitéMéthodes showRécapitulatif - Catalogue de produits8Classes de référence
Définition des classes de référenceMéthodes et mises à jour des champsSémantique de copieHéritage et callSuperRécapitulatif - File d’attente des tâches11Projet : gestion de bibliothèque
Livres et membresEmprunter des livres3Héritage S3
Vecteurs de classesOrdre de recherche des méthodesÉtendre avec NextMethodVérifier avec inherits()Récapitulatif - Paie du personnelEntraînez-vous par vous-même : Compilateur R en ligne