
本文介绍如何使用递归函数将形如 ["&&", ["==", "a", "b"], ["&&", ...]] 的嵌套条件数组,精准渲染为语义清晰、层级对应的 HTML 无序列表,支持后续双向编辑(列表 ↔ 数组)扩展。
本文介绍如何使用递归函数将形如 `["&&", ["==", "a", "b"], ["&&", ...]]` 的嵌套条件数组,精准渲染为语义清晰、层级对应的 html 无序列表,支持后续双向编辑(列表 ↔ 数组)扩展。
在构建动态查询过滤器(如 JSON-based WHERE 条件编辑器)时,常需将树状逻辑结构(如 &&、||、== 等操作符与操作数组成的嵌套数组)可视化为直观的 HTML 列表。核心挑战在于:正确识别操作符位置、区分原子条件与子表达式,并递归生成嵌套 <ul> 结构。
以下是一个健壮、简洁且可读性强的纯 JavaScript 实现方案:
const arr = [
"&&",
["==", "first", "1-1"],
["&&", ["==", "second1", "2-1"], ["==", "second2", "2-2"]]
];
const generateHTMLAux = ([op, ...conds]) => {
// 若剩余条件中首个元素是数组 → 当前为复合节点(含子条件)
if (Array.isArray(conds[0])) {
return `<li>${op}
<ul>
${conds.map(generateHTMLAux).join('')}
</ul>
</li>`;
}
// 否则为叶子节点:格式为 [op, left, right] → 渲染为 "left op right"
else if (conds.length >= 2) {
const [left, right] = conds;
return `<li>${left} ${op} ${right}</li>`;
}
// 边界防护:空或异常结构返回空 li
else {
return `<li>${op}</li>`;
}
};
const generateHTML = (arr) => `<ul>${generateHTMLAux(arr)}</ul>`;
// 使用示例
const htmlOutput = generateHTML(arr);
document.body.innerHTML = htmlOutput;
console.log(htmlOutput); // 查看生成的标准化 HTML 字符串✅ 关键设计说明:
- 使用 ES6 参数解构 ([op, ...conds]) 直接分离操作符与子条件,语义清晰;
- 通过 Array.isArray(conds[0]) 判断是否进入递归分支——这是识别嵌套逻辑块的核心依据;
- 叶子节点统一按 [op, left, right] 三元结构处理(如 ["==", "first", "1-1"]),输出 first == 1-1,符合自然阅读习惯;
- 所有递归调用均返回完整 <li> 字符串,由 join('') 组合,避免 DOM 操作开销,适合服务端渲染或后续解析。
⚠️ 注意事项:
立即学习“前端免费学习笔记(深入)”;
- 该函数假设输入数组严格遵循 (operator, ...subexpressions | left, right) 结构;若存在不规范数据(如 ["&&"] 或 ["==", "a"]),建议前置校验或增强 else 分支容错逻辑;
- 如需支持双向编辑(修改 DOM 后反向生成数组),应为每个 <li> 添加 data-path 或 data-type 属性标识节点类型,并监听 input/drop 等事件重建数组;
- 生产环境若需更高性能或更复杂样式(如折叠/展开、拖拽排序),可结合轻量库如 SortableJS 或使用 React/Vue 封装为受控组件。
此方案无需外部依赖,代码精炼、逻辑自洽,是构建条件可视化编辑器的理想起点。



















