是否有“内置”/高效且可靠的方法来检查列表对象是否嵌套?
澄清我对嵌套一词的理解:
平面或非嵌套列表
x.1 <- list(
a=TRUE,
b=1:5
)
嵌套列表
x.2 <- list(
a=list(a.1=list(a.1.1=TRUE)),
b=list(b.1=1:5)
)
我的第一个想法是使用str
,capture.output
和正则表达式的组合。但是所有与正则表达式相关的东西:相当强大,在稳健性方面相当冒险;-)所以我想知道那里是否有更好的东西:
isNested <- function(x) {
if (class(x) != "list") {
stop("Expecting 'x' to be a list")
}
out <- FALSE
strout <- capture.output(str(x))
idx <- grep("\\$.*List", strout)
if (length(idx)) {
out <- TRUE
}
return(out)
}
> isNested(x=x.1)
[1] FALSE
> isNested(x=x.2)
[1] TRUE
第二种方法由罗曼和阿伦提供:
isNested2 <- function(x) {
if (class(x) != "list") {
stop("Expecting 'x' to be a list")
}
out <- any(sapply(x, is.list))
return(out)
}
> isNested2(x=x.1)
[1] FALSE
> isNested2(x=x.2)
[1] TRUE
答案 0 :(得分:7)
您可以使用is.list
功能:
any(sapply(x.1, is.list))
[1] FALSE
any(sapply(x.2, is.list))
[1] TRUE
作为一个函数isNested
:
isNested <- function(l) {
stopifnot(is.list(l))
for (i in l) {
if (is.list(i)) return(TRUE)
}
return(FALSE)
}
该函数在检测到嵌套列表后立即停止,而不是测试所有列表元素。
答案 1 :(得分:2)
试试这个:
isNested <- function(x) {
if (is.list(x))
stop("Expecting 'x' to be a list")
any(unlist( lapply(x,is.list) ))
}
答案 2 :(得分:2)
这是另一种有趣的方式:
length(unlist(l, FALSE)) != length(unlist(l))
或者对此有所不同:
!identical(unlist(l, FALSE), unlist(l))
使用recursive
的{{1}}参数。如果你想要错误检查:
unlist()