如何基于Or、And对象树生成指定格式的整数嵌套列表
实现思路
这个需求本质是嵌套逻辑表达式的析取范式展开,规则如下:
Single节点:代表单个固定值,展开后返回仅包含该值的单条路径数组Ors节点:代表多选一分支,展开后返回所有子节点展开结果的合并集合Ands节点:代表全选拼接,展开后对所有子节点的展开结果做笛卡尔积,再把每条乘积对应的子数组合并为一条完整路径
JS 完整实现代码
// 定义三类节点 class Single { constructor(value) { this.value = value } } class Ands { constructor(items) { this.items = items } } class Ors { constructor(items) { this.items = items } } // 快捷创建Single节点的方法 const single = val => new Single(val) // 核心展开函数 function expand(node) { // 处理Single节点:返回单条路径 if (node instanceof Single) { return [[node.value]] } // 处理Ors节点:合并所有子节点的展开结果 if (node instanceof Ors) { return node.items.flatMap(child => expand(child)) } // 处理Ands节点:计算所有子节点展开结果的笛卡尔积,再拼接路径 if (node instanceof Ands) { // 先递归展开所有子节点 const childExpansions = node.items.map(child => expand(child)) // 计算笛卡尔积 return childExpansions.reduce((acc, curr) => { const result = [] for (const a of acc) { for (const b of curr) { result.push([...a, ...b]) } } return result }, [[]]) } return [] } // 测试用例 const andsOrs = new Ands([ single(1), new Ors([ single(2), single(3), new Ands([ single(4), single(5), new Ors([ single(6), single(7) ]) ]) ]) ]) console.log(expand(andsOrs)) // 输出:[[1,2],[1,3],[1,4,5,6],[1,4,5,7]]
逻辑说明
- 递归终止条件为遇到
Single节点,直接返回包裹后的单元素路径数组 Ors节点利用flatMap直接拍平子节点的展开结果,符合多选一的语义Ands节点的笛卡尔积计算是核心:初始值为[[]],依次和每个子节点的展开结果做两层循环拼接,最终得到所有可能的组合路径
内容的提问来源于stack exchange,提问作者atreeon
相关产品推荐
相关产品推荐

