我编写了一个包含以下函数的堆栈“class”:add
,push
,pop
,size
,isEmpty
,{{1} (还有一些)。
我想在R中使用这个“类”作为泛型,所以我可以在我的脚本中创建多个堆栈实例。我该怎么做呢?
(我的引号中有类,因为我的堆栈函数是用不同的脚本编写的(不一定是类本身的定义)
提前致谢
clear
答案 0 :(得分:5)
这是一个更简单的堆栈实现@GSee引用版本,它避免使用R中可用的任何正式的面向对象系统。简化从R中的所有函数都是闭包这一事实开始,函数调用期间创建的函数是绑定到为该调用创建的环境。
new_stack <- function() {
stack <- vector()
push <- function(x) stack <<- c(stack, x)
pop <- function() {
tmp<-tail(stack, 1)
stack<<-stack[-length(stack)]
return(tmp)
}
structure(list(pop=pop, push=push), class='stack')
}
x <- new_stack()
x$push(1:3)
x$pop()
# [1] 3
x$pop()
# [1] 2
这是一个S4实现,用于比较。
setClass('Stack',
representation(list='list', cursor='numeric'), # type defs
prototype(list=list(), cursor=NA_real_)) # default values
setGeneric('push', function(obj, ...) standardGeneric('push'))
setMethod('push', signature(obj='Stack'),
function(obj, x) {
obj@list <- c(x, obj@list)
obj
})
setGeneric('pop', function(obj, ...) standardGeneric('pop'))
setMethod('pop', signature(obj='Stack'),
function(obj) {
obj@cursor <- obj@list[[1]]
obj@list <- obj@list[-1]
obj
}
)
x <- new('Stack')
# cursor is empty to start
x@cursor
#[1] NA
# add items
x <- push(x, 1)
x <- push(x, 2)
# pop them (move next item to cursor, remove from list)
x <- pop(x)
x@cursor
# [1] 2
x <- pop(x)
x@cursor
# [1] 1
答案 1 :(得分:3)
由于你是专门讨论使用push和pop方法的堆栈“类”,这里是Jeff Ryan从Introducing Closures获取的一个实现,你可以阅读它来解释这里发生了什么。
new_stack <- function() {
stack <- new.env()
stack$.Data <- vector()
stack$push <- function(x) .Data <<- c(.Data,x)
stack$pop <- function() {
tmp <- .Data[length(.Data)]
.Data <<- .Data[-length(.Data)]
return(tmp)
}
environment(stack$push) <- as.environment(stack)
environment(stack$pop) <- as.environment(stack)
class(stack) <- "stack"
stack
}
> x <- new_stack()
> x$push(1:3)
> x$pop()
[1] 3
> x$pop()
[1] 2
然后,如果您创建S3泛型......
push <- function(x, value, ...) UseMethod("push")
pop <- function(x, ...) UseMethod("pop")
push.stack <- function(x, value, ...) x$push(value)
pop.stack <- function(x) x$pop()
> push(x, 5)
> pop(x)
[1] 5
> pop(x)
[1] 1