Подтвердить что ты не робот

Эффективно удалите все значения NULL в списке и все подписи

Рассмотрим следующий список:

> l1 <- list(NULL,1,2,list(NULL,3,list(NULL,4)))
> str(l1)
List of 4
 $ : NULL
 $ : num 1
 $ : num 2
 $ :List of 3
  ..$ : NULL
  ..$ : num 3
  ..$ :List of 2
  .. ..$ : NULL
  .. ..$ : num 4

Чтобы удалить значения NULL с первого уровня, просто вызовите

l1[vapply(l1,is.null,logical(1L))] <- NULL

Теперь я хочу удалить все значения NULL на всех уровнях, я придумал следующий код.

list.clean <- function(.data, fun = is.null, recursive = FALSE) {
  if(recursive) {
    .data <- lapply(.data, function(.item) {
      if(is.list(.item)) list.clean(.item, fun, TRUE)
      else .item
    })
  }
  .data[vapply(.data,fun,logical(1L))] <- NULL
  .data
}

И вызов

> list.clean(l1, recursive = TRUE)
[[1]]
[1] 1

[[2]]
[1] 2

[[3]]
[[3]][[1]]
[1] 3

[[3]][[2]]
[[3]][[2]][[1]]
[1] 4

Хотя он работает прямо сейчас, есть ли лучший или более быстрый способ сделать это?

4b9b3361

Ответ 1

Это можно сделать рекурсивно:

rmNull <- function(x) {
   x <- Filter(Negate(is.null), x)
   lapply(x, function(x) if (is.list(x)) rmNull(x) else x)
}
l2 <- rmNull(l1)

даяние:

> str(l2)
List of 3
 $ : num 1
 $ : num 2
 $ :List of 2
  ..$ : num 3
  ..$ :List of 1
  .. ..$ : num 4