inst/examples/ihasNext.R

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))

Try the iterators package in your browser

Any scripts or data that you put into this service are public.

iterators documentation built on Feb. 5, 2022, 1:06 a.m.