File: ihasNext.R

package info (click to toggle)
r-cran-iterators 1.0.7-1
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 532 kB
  • sloc: sh: 29; makefile: 1
file content (71 lines) | stat: -rw-r--r-- 1,670 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
library(iterators)

# This example was originally written and contributed
# by Hadley Wickham, with minor modifications by
# Revolution Analytics

# Define a hasNext generic function
hasNext <- function(obj, ...) {
  UseMethod('hasNext')
}

# Define a hasNext method for the "ihasNext" class
hasNext.ihasNext <- function(obj, ...) {
  obj$hasNext()
}

# This function takes an iterator and returns an iterator that supports
# the "hasNext" method.  This simplifies manually calling the "nextElem"
# method of the iterator, since you don't have to worry about catching
# the "StopIteration" exception.
ihasNext <- function(it) {
  it <- iter(it)

  # If "it" already has a hasNext function, return it unchanged
  if (!is.null(it$hasNext))
    return(it)

  cache <- NULL
  has_next <- NA

  nextEl <- function() {
    if (!hasNx())
      stop('StopIteration', call.=FALSE)

    # Reset the "has_next" flag and return the value
    has_next <<- NA
    cache
  }

  hasNx <- function() {
    # Check if you already know the answer
    if (!is.na(has_next))
      return(has_next)

    # Try to get the next element
    tryCatch({
      cache <<- nextElem(it)
      has_next <<- TRUE
    },
    error=function(e) {
      if (identical(conditionMessage(e), 'StopIteration')) {
        has_next <<- FALSE
      } else {
        stop(e)
      }
    })

    has_next
  }

  obj <- list(nextElem=nextEl, hasNext=hasNx)
  class(obj) <- c('ihasNext', 'abstractiter', 'iter')
  obj
}

# Create a "counting" iterator that has a hasNext method
it <- ihasNext(icount(3))

# Print the values of the iterator without the need for error handling
while (hasNext(it))
  print(nextElem(it))