检查列表是否嵌套

时间:2013-03-13 10:04:55

标签: r list nested nested-lists

是否有“内置”/高效且可靠的方法来检查列表对象是否嵌套?

澄清我对嵌套一词的理解:

平面或非嵌套列表

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)
)

我的第一个想法是使用strcapture.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

3 个答案:

答案 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()