Yineleyici Kalıbı
Coddy'nin R Journey'sinin Nesne Tabanlı Programlama bölümünün bir parçası. Ders 49 / 57.
Bir iterator, bir koleksiyonun öğelerini teker teker sağlar; böylece bunları kullanan kodun koleksiyonun nasıl depolandığını bilmesi gerekmez. Bir closure konumu korur; has_next() ve next_value() arayüzün tamamıdır:
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(), "")Çıktı:
a b c Bir üretici, istendiğinde her değeri hesaplayan bir yineleyicidir; bu nedenle dizinin bellekte bulunması gerekmez. Hatta sonsuz olabilir:
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(), "")Çıktı:
0 1 1 2 3 5 8 13 21 34 Yineleyici düzeni gizler. Sayfalarda saklanan sonuçlar, bazıları boş olsa bile tek bir düz dizi olarak dışarı çıkar:
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(), "")Çıktı:
a b c Arayüze göre yazılan yardımcılar her yineleyiciyle çalışır. take(it, n), bir vektörden, bir üreteçten veya has_next() ve next_value() işlevlerine sahip başka herhangi bir şeyden en fazla n değer çeker:
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))Çıktı:
[1] 1 2
[1] 3 4 5Görev
KolayIterator.R dosyasını tamamlayın:
make_iterator(x): bir vektörün öğeleri üzerinde,has_next()venext_value()işlevlerine sahip bir yineleyici;make_range(from, to, by):from,from + by, ... değerlerinitodahil olacak şekilde her seferinde bir tane hesaplayan bir üreteç;take(it, n): herhangi bir yineleyicinin en fazlansonraki değeri.
Sağlanan kod, range 1 10 3 take 2 5 (from, to, by ve ardından her take işleminin boyutları) veya list a,b,c take 2 2 biçimindeki satırları okur ve her take() işleminin döndürdüğü değerleri yazdırır.
Kodunuz Iterator.R dosyasına yazılmalıdır. main.R sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.
Kendin dene
source("Iterator.R")
# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
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 = "")
}
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Tabanlı Programlama bölümündeki tüm dersler
1S3 Temelleri
Dosyalarla ÇalışmaSınıf ile ListelerYapıcı FonksiyonlarPrint ve Format MetotlarıDoğrulayıcılar ve YardımcılarTekrar - Sıcaklıklar4R'da Kapsülleme
Nesne Olarak Closure'larNesne Olarak OrtamlarErişimci FonksiyonlarDurumu KorumaÖzet - Parkmetre2S3 Generic'leri ve Metotları
Generic'ler ve UseMethodVarsayılan MetotlarTemel Generic'ler için MetotlarNextMethod TemelleriTekrar - Şekil Alanları5S4 Sınıfları
S4 Sınıflarını TanımlamaSlotlar ve ErişimGeçerlilik KontrolleriShow MetotlarıÖzet - Ürün Kataloğu8Referans Sınıfları
Referans Sınıflarını TanımlamaMetotlar ve Alan GüncellemeleriKopyalama SemantiğiKalıtım ve callSuperÖzet - Görev Kuyruğu11Proje: Kütüphane Yönetimi
Kitaplar ve ÜyelerKitap Ödünç AlmaKendi başına pratik yap: Online R derleyicisi