
本文介绍如何使用递归函数将表示布尔逻辑条件的嵌套 javascript 数组(如 ["&&", ["==", "a", "b"], ...])精准渲染为语义化、层级清晰的 html 无序列表,支持后续双向编辑(dom ↔ 数组)扩展。
本文介绍如何使用递归函数将表示布尔逻辑条件的嵌套 javascript 数组(如 ["&&", ["==", "a", "b"], ...])精准渲染为语义化、层级清晰的 html 无序列表,支持后续双向编辑(dom ↔ 数组)扩展。
在构建动态查询条件编辑器(如可视化 WHERE 子句配置面板)时,常需将结构化的逻辑数组(例如 ["&&", ["==", "name", "John"], ["&&", ["!=", "age", "0"], [")转化为直观的树形 HTML 列表。该结构天然适合递归处理:每个子数组以操作符(如 <code>"&&"、"==")开头,后跟一个或多个操作数——若操作数为数组,则代表嵌套子条件;若为字符串,则为原子值。
核心思路是分离操作符与子条件,并根据子项类型分治处理:
- 若当前子条件(
conds[0])为数组 → 递归生成嵌套<ul></ul>; - 若为字符串(即
conds = [left, op, right]形式中的左右值)→ 拼接为终端<li>,格式为"left op right"。
以下为健壮、可复用的实现:
const generateHTMLAux = ([op, ...conds]) => {
// 基础校验:空数组或非数组输入直接返回空字符串
if (!Array.isArray(conds) || conds.length === 0) return '';
// 判断首个子项是否为嵌套数组(即存在子条件分支)
if (Array.isArray(conds[0])) {
return `<li>${op}
<ul>
${conds.map(generateHTMLAux).join('')}
</ul>
</li>`;
} else {
// 终止情况:conds 应为 [left, right] 或 [left, op, right],
// 但原始数据约定为 [op, left, right],故此处需适配:实际传入的是 [left, right](因 op 已提取)
// ⚠️ 注意:原题示例中 arr 结构为 [op, ...subConditions],且 subConditions 中每个元素自身也是 [op, a, b] 或 [op, ...]
// 因此 conds[0] 是完整子数组,而 conds.length > 1 时才可能有多个并列条件(如 && 的多个分支)
// 所以更准确的终止逻辑是:当 conds 中所有项均为字符串(非数组)时,按顺序两两配对
// 但题设结构明确:每个非顶层节点必为 [op, a, b] 或 [op, ...subArrays],因此我们统一按“首项是否为数组”判断
// 故此处 else 分支实际不会触发——因为 conds 元素要么是数组(递归),要么结构非法
// 正确做法:仅当 conds 长度为 2 且二者均为字符串时,才视为原子比较
const [left, right] = conds;
return `<li>${left} ${op} ${right}</li>`;
}
};
// 主入口:包裹顶层 ul
const generateHTML = (arr) => {
if (!Array.isArray(arr) || arr.length < 1) return '<ul></ul>';
return `<ul>${generateHTMLAux(arr)}</ul>`;
};✅ 使用示例:
实现 Markdown↔ HTML 互转,支持导出 PDF,用于用户请求的文档格式转换。
立即学习“前端免费学习笔记(深入)”;
const arr = [ "&&", ["==", "first", "1-1"], ["&&", ["==", "second1", "2-1"], ["==", "second2", "2-2"]] ]; document.body.innerHTML = generateHTML(arr);
⚠️ 注意事项:
- 该函数假设输入结构严格符合
[operator, ...conditions]范式,不校验操作符合法性(如"=="、"&&"),生产环境建议增加op白名单校验; - 当前实现生成纯字符串 HTML,如需绑定事件(如点击添加/删除节点),应改用
document.createElement动态构建 DOM 并附加data-*属性标记来源索引; - 反向解析(DOM → 数组)需遍历
<li>的textContent与子<ul></ul>结构,提取操作符及子节点,是本方案的自然延伸,可基于Element.children和正则匹配(\S+)\s+(==|!=|&&|\|\|)\s+(\S+)实现。
此方法轻量、无依赖、语义清晰,是构建 JSON 查询条件可视化编辑器的理想起点。


















