2013-03-13 142 views
3

是否有一個「內置」/有效和健壯的方式來檢查列表對象是否嵌套?檢查一個列表是否嵌套

爲了澄清我的術語的理解嵌套

平或不嵌套列表

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

我的第一個想法是使用的組合,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 
+1

如果您是第一個訂單清單,如果班級是清單,該怎麼辦?如果是的話,它是嵌套的,否則不是。 (任何(sapply(x.2,function(x)class(x)==「list」))''的行。 'any(sapply(x.1,function(x)class(x)==「list」))'返回FALSE。 – 2013-03-13 10:06:33

+1

'any(sapply(my_list,class)==「list」)' – Arun 2013-03-13 10:07:54

+0

好吧,那會更容易;-)謝謝你們!作爲第二種方法嵌入您的方法。歡呼 – Rappster 2013-03-13 10:10:57

回答

6

可以使用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) 
} 

而是測試所有列表中的元素,功能,因爲它檢測到一個嵌套列表就停止。

2

試試這個:

isNested <- function(x) { 
    if (is.list(x)) 
     stop("Expecting 'x' to be a list") 

    any(unlist(lapply(x,is.list))) 
    } 
+0

謝謝你的回答並把它放到「我的函數上下文」中!把它交給斯文,因爲它只是更簡潔一點而已。乾杯 – Rappster 2013-03-13 10:25:44

2

這裏的另一種方式爲它的樂趣:

length(unlist(l, FALSE)) != length(unlist(l)) 

或者在一個變化:

!identical(unlist(l, FALSE), unlist(l)) 

利用的recursive參數unlist()。如果您想要,還可以進行錯誤檢查:

isNested <- function(l) { 
    if (!is.list(l)) stop("Not a list.") 
    !identical(unlist(l, FALSE), unlist(l)) 
}