一个更好的方法来推送和弹出到/从R中的列表?

xj3cbfub  于 2023-01-28  发布在  其他
关注(0)|答案(5)|浏览(123)

如果是foo <- list(),我发现自己写了很多foo[[length(foo)+1]] <- bar,而实际上我只想写push(foo, bar)
类似地(尽管不太常见),bar <- foo[[length(foo)]]会比bar <- pop(foo)好得多。
1.有没有更好的方法在R基上做这件事?
1.如果做不到这一点,有没有人编写了一个包,使这些基本的列表操作在语法上不那么痛苦?
让我头疼的是变量名的重复。

anInformative.selfDocumenting.listName[[length(anInformative.selfDocumenting.listName)+1]] <- bar

编辑:
foo <- append(foo, bar)不适合我

foo <- list()
for (i in 1:10) {
  x <- data.frame(a=i, b=rnorm(1,0,1))
  foo[[length(foo)+1]] <- x
}
str(foo)

按预期提供10个对象的列表。

foo <- list()
for (i in 1:10) {
  x <- data.frame(a=i, b=rnorm(1,0,1))
  foo <- append(foo, x)
}
str(foo)

提供包含20个对象的列表。

1tuwyuhd

1tuwyuhd1#

foo[[length(foo)+1]] <- bar

可以改写为

foo <- append(foo, bar)

以及

bar <- foo[[length(foo)]]

可以改写为

bar <- tail(foo,1)

注意,对于像R这样的函数式语言,函数通常不应该改变传递给它们的参数值;通常你会返回一个新的对象,你可以把它赋值给其他地方。2这个函数应该没有“副作用”。3像push/pop这样的函数在其他语言中通常会修改一个传递过来的参数。

nue99wik

nue99wik2#

虽然晚了几年,但是这里有一种需要最少输入的方法,注意pop从对象中删除了最后一个元素。

push <- function(obj, input) {
  variable <- deparse(substitute(obj))
  out <- get(variable, envir = parent.frame(n=2))
  out[[length(out)+1]] <- input
  assign(variable, out, envir = parent.frame(n=2))
}

pop <- function(obj) {
  variable <- deparse(substitute(obj))
  obj <- get(variable, envir = parent.frame(n=2))
  
  if (length(obj) > 0) {
    out <- obj[[length(obj)]]
    assign(variable, obj[-length(obj)], envir = parent.frame(n=2))
  }else{
    out <- NULL
    assign(variable, out, envir = parent.frame(n=2))
  }
  
  return(out)
}

示例:

> foo <- list()
> push(foo, "a")
> push(foo, "b")
> foo
[[1]]
[1] "a"

[[2]]
[1] "b"

> pop(foo)
[1] "b"
> foo
[[1]]
[1] "a"
zc0qhyus

zc0qhyus3#

pushR = function(foo, bar){
  foo[[length(foo)+1]] <- bar
  foo
}

popR=function(foo){
  foo[[length(foo)]]
}

foo <- list()
for (i in 1:10) {
  x <- data.frame(a=i, b=rnorm(1,0,1))
  foo <- pushR(foo, x)
}

popR(foo)
piah890a

piah890a4#

foo <- list()
for (i in 1:10) {
  x <- data.frame(a=i, b=rnorm(1,0,1))
  foo[[length(foo)+1]] <- x
}

可以写成:

foo <- list()
for (i in 1:10) {
 x <- data.frame(a=i, b=rnorm(1,0,1))
 foo[[i]] <- x
}

如果您担心重复变量名,我完全同意lapply的工作效率更高,无论是在性能上还是在整个代码的长度上。

2guxujil

2guxujil5#

这是简单和干净的关闭

makeStack <- function() {
    valueList <- list()
    list(
        push = function(value) {
            valueList <<- append(valueList, value)
        },
        pop = function() {
            value <- utils::tail(valueList, 1)[[1]]
            valueList <<- utils::head(valueList, -1)
            value
        }
    )
}
> stack <- makeStack()
> stack$push(3)
> stack$push(5)
> stack$pop()
[1] 5
> stack$pop()
[1] 3

相关问题