Shixiang Wang

>上士闻道
勤而行之

unlist() 和 purrr::flatten() 的区别在哪里?

王诗翔 · 2020-12-02

分类: r  
标签: r   purrr  

最近在工作的时候有一个需求是解除对象的列表结构,但运行后发现 unlist() 并非我想要的只解除一层嵌套。

我们用个非常简单的数据来看这个问题:

x <- list(list(a = 1, b = 2))
x
#> [[1]]
#> [[1]]$a
#> [1] 1
#> 
#> [[1]]$b
#> [1] 2
str(x)
#> List of 1
#>  $ :List of 2
#>   ..$ a: num 1
#>   ..$ b: num 2

如果我们使用 unlist(),结果如下:

unlist(x)
#> a b 
#> 1 2

可能这是我们大多数想要的场景。

但如果我们想要保留包含 ab 的那层嵌套呢?我们可以显式地指定 recursive = FALSE

unlist(x, recursive = FALSE)
#> $a
#> [1] 1
#> 
#> $b
#> [1] 2

如果你接触过 purrr 包,你可能会见过 flatten 这个函数,它也是做类似的工作。

purrr::flatten(x)
#> $a
#> [1] 1
#> 
#> $b
#> [1] 2

可以看到,flatten() 默认只解除一层嵌套!

These functions remove a level hierarchy from a list. They are similar to unlist(), but they only ever remove a single layer of hierarchy and they are type-stable, so you always know what the type of the output is.

小结

unlist()purr::flatten() 都是用来解除列表的层次嵌套结构。如果我们拿拨开卷心菜作为例子,那么 unlist() 默认一次性拨完,而 purrr::flatten() 只拨开一层。