在嵌套的列表列表中查找空列表

seb*_*n-c 8 r nested-lists

给定一个任意嵌套的列表,如何找到列表是否包含空列表?请考虑以下示例:

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

我试过了rapply,但是跳过了列表.虽然我可以使用lapply,但我需要事先知道嵌套的级别.对于本练习,我不需要知道列表的位置(虽然这将是一个奖励),我只需要一种方法来检测是否有一个.

MrF*_*ick 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)
    }
}
Run Code Online (Sandbox Code Playgroud)

基本上我们创建一个递归函数来查找长度为0的列表.

has_empty_list( list(list("foo", "bar", "baz", list(list()))) )
# TRUE
has_empty_list( list(list("foo", "bar", "baz", list(list(4)))) )
# FALSE
Run Code Online (Sandbox Code Playgroud)

这是一个修改,以找到空列表的索引

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())
    }
}
Run Code Online (Sandbox Code Playgroud)

这应该返回索引的向量,您可以使用该向量来查找空列表.例如

( i <- find_empty_list(mylist) )
# [1] 1 4 1
mylist[[i]]
# list()
Run Code Online (Sandbox Code Playgroud)

如果第一个参数本身是一个空列表,它将返回0

find_empty_list(list())
# 0
Run Code Online (Sandbox Code Playgroud)

如果没有空列表,则应返回空向量

find_empty_list(list(1:3, list("c", a~b)))
# numeric()
Run Code Online (Sandbox Code Playgroud)


Psi*_*dom 5

使用嵌套列表的另一个方便的选择是使用data.tree包:

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