如何在嵌套列表中自动查找元素路径(含无命名元素场景)
嵌套列表指定元素的自动路径生成(支持无命名元素)
针对网页抓取中从JSON解析的嵌套列表(含无命名元素),可以通过递归遍历实现自动定位指定值的路径,生成的路径可直接传入purrr::pluck调用,无需手动推导索引。
实现递归查找函数
以下函数会遍历嵌套列表,返回所有匹配目标值的路径(路径为混合字符/数字的向量,直接兼容pluck):
library(purrr) find_element_paths <- function(lst, target, current_path = c()) { paths <- list() # 遍历列表的每个元素,同时获取名称/索引 for (i in seq_along(lst)) { elem <- lst[[i]] # 确定当前节点的标识:有名称用名称,无名称用索引 node_id <- if (!is.null(names(lst)) && names(lst)[i] != "") names(lst)[i] else i # 如果当前元素是列表,递归查找 if (is.list(elem)) { sub_paths <- find_element_paths(elem, target, c(current_path, node_id)) paths <- c(paths, sub_paths) } else { # 如果匹配目标值,记录当前路径 if (elem == target) { paths <- c(paths, list(c(current_path, node_id))) } } } paths }
测试案例
1. 含无命名元素的列表(用户示例l2)
l2 <- list(x = list("no_match", list("test_noname1", "test_noname2")), y = list(a = "test_name")) # 查找"test_noname1"的路径 paths <- find_element_paths(l2, "test_noname1") paths # [[1]] # [1] "x" 2 1 # 直接用pluck访问元素 pluck(l2, !!!paths[[1]]) # [1] "test_noname1"
2. 全命名嵌套列表(用户示例l1)
l1 <- list(x = list(a = "no_match", b = "test_noname", c ="test_noname"), y = list(a = "test_name")) # 查找"test_noname"的所有路径 paths <- find_element_paths(l1, "test_noname") paths # [[1]] # [1] "x" "b" # [[2]] # [1] "x" "c" # 访问第一个匹配元素 pluck(l1, !!!paths[[1]]) # [1] "test_noname"
获取同级未知元素
找到目标元素路径后,只需去掉路径的最后一个节点,即可获取父节点路径,进而提取同级元素:
# 以l2中"test_noname1"为例,获取其同级的"test_noname2" target_path <- paths[[1]] parent_path <- target_path[-length(target_path)] # 父节点是l2[["x"]][[2]],直接取所有子元素 pluck(l2, !!!parent_path) # [[1]] # [1] "test_noname1" # [[2]] # [1] "test_noname2" # 直接取第二个同级元素 pluck(l2, !!!parent_path, 2) # [1] "test_noname2"
内容的提问来源于stack exchange,提问作者JBGruber
相关产品推荐
相关产品推荐

