In genere, si rimuove NULL
elementi su una semplice lista con
ll <- list(1, 2, NULL, 3)
ll <- ll[ ! sapply(ll, is.null) ]
Se non si conosce la struttura in anticipo, questo è un chiaro caso di combinare questa soluzione con una funzione ricorsiva:
removeNullRec <- function(x){
x <- x[ !sapply(x, is.null) ]
if(is.list(x)){
x <- lapply(x, removeNullRec)
}
return(x)
}
removeNullRec(tmp)
[[1]]
[[1]][[1]]
[[1]][[1]][[1]]
[1] 2 9 10
[[1]][[2]]
[1] 1 3 4 6
[[2]]
[1] 7
Modifica
E 'sempre bene di riformulare il problema il più semplice possibile. Quello che ho capito dai tuoi commenti è che (indipendentemente dall'occorrenza degli elementi NULL
) che vuoi sostituire ogni elemento che contiene solo un figlio dal bambino stesso. C'è anche un altro caso che deve essere considerato allora: due foglie di pari livello potrebbero essere NULL
pure. Quindi, consente di iniziare con un po 'esempio più complesso:
tree <- list(
list(
list(
list(
list(NULL, NULL),
list(NULL, NULL)
),
7
),
list(
list(
list(c(1,2), NULL),
c(3,4)
))))
Questo problema isolato al piatto l'albero è, naturalmente, anche risolti meglio applicando approccio ricorsivo:
flatTreeRec <- function(x){
if(is.list(x)){
# recursion
x <- lapply(x, flatTree)
# remove empty branches
x <- x[ sapply(x, length) > 0 ]
# flat branches with only child
if(length(x) == 1){
x <- x[[1]]
}
}
return(x)
}
flatTreeRec(removeNullRec(tree))
E Ovviamente puoi combinare direttamente queste due funzioni per evitare di stressare lo stack due volte:
removeNullAndFlatTreeRec <- function(x){
x <- x[ !sapply(x, is.null) ]
if(is.list(x)){
x <- lapply(x, removeNullRec)
x <- x[ sapply(x, length) > 0 ]
if(length(x) == 1){
x <- x[[1]]
}
}
return(x)
}
removeNullAndFlatTreeRec(tree)
Grazie mille! Mi chiedevo se la lista che contiene l'elemento NULL potesse essere non elencata dall'elenco annidato. Per il mio esempio precedente, se un elemento NULL viene rilevato nell'elenco, quindi non elenco l'elenco, in modo che l'elenco nidificato ha solo 2 elenchi. cioè, lista (lista (c (2,9,10), c (1,3,4,6)), 7). La tua funzione conserva lo stesso numero di liste presenti nell'elenco originale. – user2498497
Grazie!Il tuo codice funziona nella rimozione dell'elemento NULL. Tuttavia non rimuove/non elenca l'elenco che contiene l'elemento NULL. – user2498497
@ user2498497 in quali casi vuoi escludere dalla lista i fratelli dell'elemento 'NULL'? Solo se è l'unico fratello ed è piatto (cioè non contiene bambini)? E i casi in cui un elemento della lista è l'unico elemento nella gerarchia ed è piatto. Vuoi che non siano in elenco anche se non esiste un fratello 'NULL'? Quale dovrebbe essere il risultato corretto di 'lista (lista (lista (1,2,3), NULL))'? – Beasterfield