Henrik Bengtsson
2011-Feb-14 01:19 UTC
[Rd] Wish: Iterate over any data type/object 'xs' in for (x in xs) { ... }
Hi, this is about iterating over any data type/object 'xs' in the for-loop constructor: for (x in xs) { ... }>From help("for"), on can read that 'xs' has to be "An expressionevaluating to a vector (including a list and an expression) or to a pairlist or NULL. A factor value will be coerced to a character vector". If you have a data type/class that contains items that you wish to iterate over, you could write a as.sequence() method that returns a vector to iterate over, e.g. for (x in as.sequence(xs)) { print(x); } For cases where 'xs' in for (x in xs) { ... } is not a vector (or a pairlist or NULL), would it be possible to extend R such that it automatically do the above? Here is an example based on an S3 class illustrating this: Letter <- function(i) { structure(i, class="Letter"); } as.character.Letter <- function(x, ...) { base::letters[x]; } print.Letter <- function(x, ...) { print(sprintf("Letter: %s", as.character(x)), ...); } Letters <- function(n) { res <- structure(NA, class="Letters"); attr(res, "items") <- lapply(1:n, FUN=Letter); res; } as.sequence.Letters <- function(x, ...) { attr(x, "items"); } as.sequence <- function(x, ...) UseMethod("as.sequence"); xs <- Letters(5); for (x in as.sequence(xs)) { print(x); } [1] "Letter: a" [1] "Letter: b" [1] "Letter: c" [1] "Letter: d" [1] "Letter: e" What would be really nice is if one could just do: for (x in xs) { print(x); } [1] NA I'm sure this is way more complicated than I anticipate (e.g. for() is language construct), but I'd though it's worth throwing it out there. /Henrik