R/dict.R

#' @title Dict
#' @description Creates a \code{dict} object from the supplied arguments.
#'
#' A \code{dict} can be create from named arguments, named lists, environments,
#' or vectors of \code{keys} and \code{values}.
#'
#' @param ... Objects, possibly named.
#'
#' @seealso \code{\link{items}}
#'
#' @examples
#' # Basic use:
#' d <- dict(a = 1, b = 2)
#' d$size()
#' d$has_key("a")
#' d$has_key("c")
#'
#' # From a named list
#' d <- dict(list(chr = "name", bool = TRUE))
#' d$get("chr")
#' d$get("char", default = "missing")
#' d$set("char", "now i exist")
#' d$get("char", default = "missing")
#'
#' # Updating dict
#' d <- dict(one = 1L)
#' other <- dict(two = 2L, PI = 3.14)
#' d$update(other)
#' d
#'
#' # Creating from keys and values vectors
#' # These can be named explicitly, otherwise the first one
#' # is considered keys and the second, values
#' d <- dict(letters, seq_along(letters))
#'
#' # Iterating through dict (will print the key with value 10, i.e. "j")
#' for (item in d$items()) {
#'   if (item$value == 10)
#'     print(item$key)
#' }
#'
#' # Extracting values
#' d <- dict(x = 1, y = 2)
#' d["x"]
#' d["z"] <- 3
#'
#' # Vectorized assignments
#' new_keys <- c("one", "two")
#' new_vals <- c(1, 2)
#' d[new_keys] <- new_vals
#'
#' # Vectorized extractions
#' keys_to_extract <- c("x", "two")
#' d[keys_to_extract]
#'
#' @return Object of class \code{dict}.
#' @export
dict <- function(...) {
  e <- make_env(...)

  .data <-
    list(
      get = function(key, default = NULL) {
        get_from_env(e, key, default)
      },

      set = function(key, value) {
        set_in_env(key, value, e)
        invisible() # prevents capturing e
      },

      update = function(other) {
        stopifnot(class(other) == "dict")
        set_in_env(other$keys(), other$values(), e)
        invisible()
      },

      keys = function() {
        names(e)
      },

      values = function() {
        as.list.environment(e, all.names = TRUE)
      },

      items = function(n = -1L) {
        get_items(e, n)
      },

      size = function() {
        length(e)
      },

      clear = function() {
        e <<- new.env()
      },

      is_empty = function() {
        is_empty_env(e)
      },

      has_key = function(key) {
        env_has_key(e, key)
      },

      delete = function(keys) {
        rm(list = keys, envir = e)
      }
    )

  structure(.data, class = "dict")
}
skubicius/dictionary documentation built on May 7, 2019, 7:17 p.m.