R语言如何高效提取嵌套列表第二层级的唯一名称
嵌套列表第二层级名称提取方案
最高效无依赖实现
你当前的实现先通过rapply递归遍历到列表最底层再拆分名称,做了很多不必要的运算。第二层级的名称本身就直接存储在第一层级子列表的名称属性中,不需要递归访问深层节点,直接提取即可,性能远高于递归类方案,且代码更简洁:
# 提取每个第一层级元素的子名称,合并后去重 desirednames <- unique(unlist(lapply(x, names)))
运行示例数据得到的结果为c("one_1", "one_2", "one_3", "two_1", "two_2"),完全匹配需求。这个方案的计算量仅和第一层级的元素数量挂钩,和列表总深度、底层节点总数无关,列表规模越大,性能优势越明显。
正则实现方案与性能说明
如果要使用正则实现,可以基于全路径名称做匹配提取,代码如下:
# 先递归获取所有底层节点的全路径名,原匿名函数可简化 allnames <- names(rapply(x, head, n = 1)) # 正则匹配提取第二个.分隔的字段 desirednames_regex <- unique(sub("^[^.]+\\.([^.]+)\\..*", "\\1", allnames))
正则方案的运算速度并不会更快:
- 对于固定分隔符的字符串处理,你原有写法里的
strsplit(..., fixed = TRUE)是固定字符匹配,开销低于正则表达式的模式匹配,速度反而更快 - 不管是正则方案还是你原来的拆分方案,都需要先执行
rapply遍历所有最底层节点,这一步的开销远大于字符串处理本身的开销,和直接提取第二层级名称的方案相比性能差距非常明显
其他可选简洁写法
如果使用tidyverse生态的purrr包,可以写链式调用的简洁版本,性能和基础R直接提取方案接近:
library(purrr) desirednames <- x |> map(names) |> flatten_chr() |> unique()
内容的提问来源于stack exchange,提问作者ramen
相关产品推荐
相关产品推荐

