R中的lambdas列表

时间:2015-03-03 03:15:17

标签: r

我想创建一个R函数,它返回一个函数列表,每个函数都在列表的不同部分上运行。但是,由于R的范围规则,这似乎是不可能的。这是一个例子:

functiontest = function() {
    foo = list()
    for(i in 1:3) {
        fixer = function(s) { return(
            function() {
                return(s)
            }
        )}
        foo[[i]] = fixer(i)
    }
    return(foo)
}

functiontest()[[2]]() #returns 3

即使杀掉已命名的lambda“fixer”并使用立即函数也不能救我:

functiontest = function() {
    foo = list()
    for(i in 1:3) {
        foo[[i]]=(function(s) { return(
            function() {
                return(s)
            }
        )})(i)
    }
    return(foo)
}

functiontest()[[2]]() #returns 3

我希望这返回2.我如何重构此代码以便实现这一点?

感谢。

1 个答案:

答案 0 :(得分:3)

首先,您遇到的问题与范围无关。其次,我认为仅仅因为你不理解它而把一些愚蠢的东西称为是一个好主意。

在您的示例中,由于R中的延迟评估机制,列表中的所有函数都返回相同的值。请参阅help(force),它专门解决您的问题。简而言之,您需要在调用时强制评估函数,这可以通过添加force来完成:

functiontest = function() {
    foo = list()
    for(i in 1:3) {
        fixer = function(s) { 
            force(s) ### <<<---This is the only difference from your code ###
            return(
            function() {
                return(s)
            }
        )}
        foo[[i]] = fixer(i)
    }
    return(foo)
}

或者,使用更简洁的语法:

functiontest <- function()  lapply(1:3, function(s) {s; function() s})

使用示例:

> L <- functiontest()

> L[[1]]()
[1] 1

> L[[2]]()
[1] 2

> L[[3]]()
[1] 3