Zazwyczaj usunąć NULL
elementów na płaskiej listy z
ll <- list(1, 2, NULL, 3)
ll <- ll[ ! sapply(ll, is.null) ]
Jeśli nie znają strukturę z góry, jest to wyraźny przypadek łączenia tego rozwiązania z funkcji rekurencyjnej:
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
Edit
To zawsze dobry przeformułowanie problemu tak proste, jak to możliwe. Z twoich komentarzy wynika, że (niezależnie od występowania elementów NULL
) chcesz, aby zastąpić każdy element, który zawiera tylko jedno dziecko przez samo dziecko. Jest jeszcze jeden przypadek, który należy wziąć pod uwagę: Dwa liście o rodzeństwie również mogą być NULL
. Więc zacznijmy trochę bardziej skomplikowany przykład:
tree <- list(
list(
list(
list(
list(NULL, NULL),
list(NULL, NULL)
),
7
),
list(
list(
list(c(1,2), NULL),
c(3,4)
))))
to odosobniony problem płaskiego drzewa jest oczywiście również rozwiązany najlepiej stosując rekurencyjnej podejście:
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))
i Oczywiście możesz bezpośrednio łączyć te dwie funkcje, aby uniknąć dwukrotnego nacisku na swój stos:
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)
Dziękuję bardzo! Zastanawiam się, czy lista zawierająca element NULL może być niepubliczna z listy zagnieżdżonej. Dla mojego powyższego przykładu, jeśli na liście zostanie wykryty element NULL, wówczas lista zostanie usunięta, tak że lista zagnieżdżona ma tylko dwie listy. tj. lista (lista (c (2,9,10), c (1,3,4,6)), 7). Twoja funkcja zachowuje taką samą liczbę list, jak na oryginalnej liście. – user2498497
Dzięki!Twój kod działa przy usuwaniu elementu NULL. Jednak nie usuwa/nie wyświetla listy zawierającej element NULL. – user2498497
@ user2498497 w jakich przypadkach chcesz usunąć listę rodzeństwa elementu "NULL"? Tylko jeśli jest to jedyne rodzeństwo i jest płaskie (tzn. Nie zawiera żadnych dzieci)? A co z przypadkami, gdy element listy jest jedynym elementem w hierarchii i jest płaski. Czy chcesz, aby były niepubliczne, chociaż nie ma rodzeństwa "NULL"? Jaki powinien być właściwy wynik 'list (list (list (1,2,3), NULL))'? – Beasterfield