list 从列表列表中删除 NULL 元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26539441/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Remove NULL elements from list of lists
提问by Chris
How do I remove the null elements from a list of lists, like below, in R:
如何从列表列表中删除空元素,如下所示,在 R 中:
lll <- list(list(NULL),list(1),list("a"))
The object I want would look like:
我想要的对象看起来像:
lll <- list(list(1),list("a"))
I saw a similar answer here: How can I remove an element from a list?but was not able to extend it from simple lists to a list of lists.
我在这里看到了类似的答案:How can I remove an element from a list? 但无法将其从简单列表扩展到列表列表。
EDIT
编辑
Bad example above on my part. Both answers work on simpler case (above). What if list is like:
我上面的坏例子。两个答案都适用于更简单的情况(上图)。如果列表是这样的怎么办:
lll <- list(list(NULL),list(1,2,3),list("a","b","c"))
How to get:
怎么获得:
lll <- list(list(1,2,3),list("a","b","c"))
回答by Josh O'Brien
This recursive solution has the virtue of working on even more deeply nested lists.
这种递归解决方案的优点是可以处理更深的嵌套列表。
It's closely modeled on Gabor Grothendieck's answer to this quite similar question. My modification of that code is needed if the function is to also remove objects like list(NULL)
(not the same as NULL
), as you are wanting.
它与 Gabor Grothendieck 对这个非常相似的问题的回答密切相关。如果该函数还删除您想要的list(NULL)
(与 不同的NULL
)对象,则需要我修改该代码。
## A helper function that tests whether an object is either NULL _or_
## a list of NULLs
is.NullOb <- function(x) is.null(x) | all(sapply(x, is.null))
## Recursively step down into list, removing all such objects
rmNullObs <- function(x) {
x <- Filter(Negate(is.NullOb), x)
lapply(x, function(x) if (is.list(x)) rmNullObs(x) else x)
}
rmNullObs(lll)
# [[1]]
# [[1]][[1]]
# [1] 1
#
#
# [[2]]
# [[2]][[1]]
# [1] "a"
Here is an example of its application to a more deeply nested list, on which the other currently proposed solutions variously fail.
这是将其应用于更深层嵌套列表的示例,在该列表上其他当前提出的解决方案各不相同。
LLLL <- list(lll)
rmNullObs(LLLL)
# [[1]]
# [[1]][[1]]
# [[1]][[1]][[1]]
# [[1]][[1]][[1]][[1]]
# [1] 1
#
#
# [[1]][[1]][[2]]
# [[1]][[1]][[2]][[1]]
# [1] "a"
回答by David Arenburg
Here's an option using Filter
and Negate
combination
这是使用Filter
和Negate
组合的选项
Filter(Negate(function(x) is.null(unlist(x))), lll)
# [[1]]
# [[1]][[1]]
# [1] 1
#
#
# [[2]]
# [[2]][[1]]
# [1] "a"
回答by Leni Ohnesorge
Using purrr
使用 purrr
purrr::map(lll, ~ purrr::compact(.)) %>% purrr::keep(~length(.) != 0)
[[1]]
[[1]][[1]]
[1] 1
[[1]][[2]]
[1] 2
[[1]][[3]]
[1] 3
[[2]]
[[2]][[1]]
[1] "a"
[[2]][[2]]
[1] "b"
[[2]][[3]]
[1] "c"
回答by Rich Scriven
For this particular example you can also use unlist
with its recursive
argument.
对于这个特定示例,您还可以使用unlist
它的recursive
参数。
lll[!sapply(unlist(lll, recursive=FALSE), is.null)]
# [[1]]
# [[1]][[1]]
# [1] 1
#
#
# [[2]]
# [[2]][[1]]
# [1] "a"
回答by thelatemail
Since you have lists in lists, you probably need to run l/sapply
twice, like:
由于列表中有列表,您可能需要运行l/sapply
两次,例如:
lll[!sapply(lll,sapply,is.null)]
#[[1]]
#[[1]][[1]]
#[1] 1
#
#
#[[2]]
#[[2]][[1]]
#[1] "a"
回答by Raminsu
回答by bramtayl
Quick fix on Josh O'Brien's solution. There's a bit of an issue with lists of functions
快速修复 Josh O'Brien 的解决方案。函数列表有点问题
is.NullOb <- function(x) if(!(is.function(x))) is.null(x) | all(sapply(x, is.null)) else FALSE
## Recursively step down into list, removing all such objects
rmNullObs <- function(x) {
if(!(is.function(x))) {
x = x[!(sapply(x, is.NullOb))]
lapply(x, function(x) if (is.list(x)) rmNullObs(x) else x)
}
}