如何用递归函数从R语言嵌套List动态构建路径?
用递归函数生成嵌套列表的路径字符串
问题背景
给定如下嵌套R列表:
myList<-list() myList[[length(myList)+1]]<-list(text="Grandfather01",tabName='tabnameGrandfather01') myList[[length(myList)+1]]<-list(text="Grandfather02", list(text="Father02_01" ,list(text='Child02_01_01',tabName='tabNameChild02_01_01') ,list(text='Child02_01_02',tabName='tabNameChild02_01_02') ) ) myList[[length(myList)+1]]<-list(text="Grandfather03", list(text='Father03_01',tabName='tabNameFather03_01') ) myList[[length(myList)+1]]<-list(text="Grandfather04" ,list(text="Father04_01" ,list(text='Child04_01_01' ,list(text='SuperChild04_01_01_01',tabName='tabNameSuperChild04_01_01_01') ,list(text='SuperChild04_01_01_02',tabName='tabNameSuperChild04_01_01_02') ) ) ,list(text='Father05_01',tabName='tabNameFather05_01') )
需要生成一个路径列表,每个顶层列表元素对应一组路径字符串,规则如下:
- 若节点包含
tabName,则生成从顶层到该节点的路径:顶层节点直接用/+tabName;非顶层节点用上层text组成的前缀+/+tabName - 无
tabName的节点仅作为路径前缀的一部分,继续遍历其子节点
递归实现方案
递归函数定义
# 递归生成路径的辅助函数 generate_paths <- function(node, prefix = "") { current_text <- node[["text"]] paths <- character(0) # 处理当前节点的tabName(如果存在) if (!is.null(node[["tabName"]])) { paths <- c(paths, if (prefix == "") { paste0("/", node[["tabName"]]) } else { paste(prefix, node[["tabName"]], sep = "/") }) } # 提取子节点(排除text和tabName字段) children <- node[!names(node) %in% c("text", "tabName")] # 递归遍历子节点 if (length(children) > 0) { new_prefix <- if (prefix == "") current_text else paste(prefix, current_text, sep = "/") for (child in children) { paths <- c(paths, generate_paths(child, new_prefix)) } } return(paths) } # 生成最终路径列表 result_list <- lapply(myList, generate_paths)
代码说明
- 递归逻辑:
- 函数接收当前节点和路径前缀,首先检查节点是否有
tabName,若有则生成对应路径字符串 - 提取节点的子元素(除
text和tabName外的所有元素),更新路径前缀后递归遍历每个子节点,收集所有路径
- 函数接收当前节点和路径前缀,首先检查节点是否有
- 顶层遍历:
- 使用
lapply遍历myList的每个顶层元素,调用递归函数生成对应组的路径,最终得到符合要求的列表
- 使用
验证结果
运行代码后,result_list的各个元素与需求完全匹配:
# 第一个元素 result_list[[1]] #> [1] "/tabnameGrandfather01" # 第二个元素 result_list[[2]] #> [1] "Grandfather02/Father02_01/tabNameChild02_01_01" "Grandfather02/Father02_01/tabNameChild02_01_02" # 第三个元素 result_list[[3]] #> [1] "Grandfather03/tabNameFather03_01" # 第四个元素 result_list[[4]] #> [1] "Grandfather04/Father04_01/Child04_01_01/tabNameSuperChild04_01_01_01" #> [2] "Grandfather04/Father04_01/Child04_01_01/tabNameSuperChild04_01_01_02" #> [3] "Grandfather04/tabNameFather05_01"
内容的提问来源于stack exchange,提问作者Lev
相关产品推荐
相关产品推荐

