求助:递归函数处理多路径物料到产品全路径查询
解决多路径物料归属递归遍历问题
嘿,我完全懂你现在的困扰——单分支的da数据框能正常跑,但遇到db这种存在多条路径的情况,递归函数就没法把所有可能的归属路径都找出来对吧?我之前做类似BOM展开需求时也踩过这个坑,给你分享个实用的实现思路和代码:
首先,我们得先把数据框转换成邻接表的形式,这样递归查找子节点会更高效。然后写一个能遍历所有子节点分支的递归函数,收集每一条完整的路径。
代码实现
# 先模拟你的多路径数据框db(根据你期望的输出构造) db <- data.frame( parent = c("A", "B", "B", "C", "C", "D"), child = c("B", "C", "D", "E", "F", "F"), stringsAsFactors = FALSE ) # 把数据框转成邻接表:每个父节点对应子节点列表 adj_list <- split(db$child, db$parent) # 递归函数:收集从起始节点出发的所有完整路径 get_all_paths <- function(start_node, current_path = start_node) { # 如果当前节点没有子节点,返回这条完整路径 if (!start_node %in% names(adj_list)) { return(current_path) } # 遍历当前节点的每个子节点,递归延伸路径 lapply(adj_list[[start_node]], function(child) { get_all_paths(child, c(current_path, child)) }) %>% unlist(recursive = FALSE) # 展开嵌套列表,保留每条路径的独立结构 } # 从节点"A"开始获取所有路径 raw_paths <- get_all_paths("A") # 把路径转换成你要的"A-B-C-E"格式 formatted_paths <- sapply(raw_paths, function(path) paste(path, collapse = "-")) # 输出结果 print(formatted_paths)
运行这段代码后,你就能得到期望的输出:
[1] "A-B-C-E" "A-B-C-F" "A-B-D-F"
额外优化:处理循环引用
如果你的物料数据里可能存在循环(比如A→B→A这种异常情况),可以给递归函数加个visited参数记录已访问节点,避免无限递归:
get_all_paths <- function(start_node, current_path = start_node, visited = start_node) { if (!start_node %in% names(adj_list)) { return(current_path) } # 过滤掉已经访问过的子节点,防止循环 valid_children <- setdiff(adj_list[[start_node]], visited) if (length(valid_children) == 0) { return(current_path) } lapply(valid_children, function(child) { get_all_paths(child, c(current_path, child), c(visited, child)) }) %>% unlist(recursive = FALSE) }
这个逻辑的核心是:每次递归都遍历当前节点的所有子节点,把每条分支的路径都单独收集起来,最后整理成你需要的字符串格式,完美适配多路径的物料归属场景~
内容的提问来源于stack exchange,提问作者r.user.05apr
相关产品推荐
相关产品推荐

