2016-07-07 62 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