2016-07-07 99 views
8

給定一個任意嵌套的列表,如何查找列表是否包含空列表?請看下面的例子:查找列表的嵌套列表中的空列表

mylist <- list(list("foo", "bar", "baz", list(list())))

我試過rapply,但跳過通過名單。雖然我可以使用lapply,但我需要事先知道嵌套的級別。對於這個練習,我不需要知道列表的位置(雖然這將是一個獎金),但我只需要一種方法來檢測是否有一個。

+0

@MrFlick是的,這就是我之後 –

回答

8

什麼像這樣

has_empty_list <- function(x) { 
    if(is.list(x)) { 
     if (length(x)==0) { 
      return(TRUE) 
     } else { 
      return(any(vapply(x, has_empty_list, logical(1)))) 
     } 
    } else { 
     return(FALSE) 
    } 
} 

基本上是一個函數,我們創建一個遞歸函數來尋找長度爲0

has_empty_list(list(list("foo", "bar", "baz", list(list())))) 
# TRUE 
has_empty_list(list(list("foo", "bar", "baz", list(list(4))))) 
# FALSE 

的名單和這裏找到空表的索引修改

find_empty_list <- function(x, index=c()) { 
    if(is.list(x)) { 
     #list 
     if (length(x)==0) { 
      if (length(index)==0) { 
       return(0) 
      } else { 
       return(index) 
      } 
     } else { 
      m <- Map(find_empty_list, x, lapply(seq_along(x), function(i) append(index,i))) 
      # return the most deeply nested 
      return(m[[which.max(lengths(m))]]) 
     } 
    } else { 
     return(numeric()) 
    } 
} 

這應該返回一個您可以用來查找空的索引的向量名單。例如

(i <- find_empty_list(mylist)) 
# [1] 1 4 1 
mylist[[i]] 
# list() 

如果第一個參數本身就是一個空列表,它會返回0

find_empty_list(list()) 
# 0 

,如果沒有空列表,它應該返回一個空載體

find_empty_list(list(1:3, list("c", a~b))) 
# numeric() 
+1

我認爲遞歸將是一個很好的解決方法。一個微小的修改 - 我會使用'vapply(x,has_empty_list,logical(1))'。 –

+0

@ sebastian-c增加了另一個功能來查找缺失的列表以及 – MrFlick

+0

謝謝@MrFlick。找到空列表的人很好,但找到空列表的人有點棘手。它似乎有多個空列表(似乎得到最嵌套的)的麻煩。 –

5

使用嵌套列表的另一個方便選項是使用data.tree包:

library(data.tree) 
nodes <- as.Node(mylist) 
any(node$Get(function(node) length(as.list(node))) == 0) 
# [1] TRUE 
+0

似乎很慢。 – Triamus