2015-03-03 60 views
-1

我想創建一個R函數,它返回一個函數列表,每個函數在列表的不同部分上運行。但是,由於R對範圍的規定,這似乎是不可能的。這裏有一個例子:R中的lambdas列表

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 

即使殺死了名爲拉姆達「固定器」,並使用立即功能不救我:

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.如何重構這個代碼,以便這會發生?

謝謝。

回答

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