2016-07-07 19 views
8

任意のネストされたリストが与えられていると、リストに空のリストが含まれている場合はどうすれば見つけることができますか?次の例を考えてみましょう:リストのネストされたリストで空のリストを見つける

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

私はrapplyを試してみましたが、それはリストを通じてスキップします。 lapplyを使用することができますが、事前にネスティングのレベルを知る必要があります。この演習では、リストがどこにあるのかを知る必要はありませんが(ボーナスになりますが)、存在するかどうかを検出する方法が必要です。

この

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 

を探すために再帰関数を作成し、ここでは空のリストのインデックスを見つけるための修正は何

+0

@MrFlickはい、それは私が後で何をするのかです。 –

答えて

8

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

関連する問題