JS优雅实现数组转AND/OR嵌套whereConditions查询对象
更优雅的where条件组装实现
需求说明
需要将不同来源的数组元素,按指定字段名生成归属到OR分组的查询条件,最终组装为固定结构的whereConditions查询对象,期望输出结构如下:
whereConditions = { "AND": [ { "OR": [ { "alert_type_id": { "equals": "9" } }, { "alert_type_id": { "equals": "8" } } ] }, { "OR": [ { "acknowledged_by_user_id": { "equals": "2" } }, { "acknowledged_by_user_id": { "equals": "3" } } ] } ] }
数据源
let alertTypesList = [{id: 9, name: "foo"},{id:8, name: "bar"}] let acknowledgeByUserList = [{id:2, name:"foo"},{id:3, name:"bar"}]
原有实现的冗余点
原写法重复声明临时变量、重复写循环拼接逻辑、多层条件判断,后续如果新增筛选维度还要复制整段相同逻辑,可维护性差。
优化实现
核心思路是把「数据源-对应查询字段」的映射抽为统一配置,用数组原生map方法生成条件组,自动过滤空条件,不需要手动逐层展开对象:
// 筛选规则配置:格式为 [数据源数组, 对应查询字段键名] const filterRules = [ [alertTypesList, 'alert_type_id'], [acknowledgeByUserList, 'acknowledged_by_user_id'] ] const whereConditions = { AND: filterRules .map(([dataList, queryKey]) => { // 空数组直接跳过,不生成条件组 if (!dataList?.length) return null return { OR: dataList.map(item => ({ [queryKey]: { equals: item.id } })) } }) // 过滤掉空的条件项 .filter(Boolean) }
方案优势
- 无冗余临时变量,不需要为每个筛选条件单独声明存储数组
- 扩展成本极低,后续新增筛选维度只需要在
filterRules中新增一行配置即可,不需要重复编写循环、判断、拼接逻辑 - 用原生数组方法代替手动循环+展开运算符拼接,执行效率更高,代码可读性更强
- 自动处理空数组场景,不需要多层
if判断做非空校验
内容的提问来源于stack exchange,提问作者Joseph Ng
相关产品推荐
相关产品推荐

