You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript实现支持多属性嵌套、AND逻辑的可扩展通用过滤函数

可扩展通用多条件AND过滤函数实现

原有实现存在的问题

  • 硬编码判断分支:每新增1个筛选维度,需要补充2^n个if/else判断,可扩展性极差
  • 不支持嵌套属性读取:无法直接读取props.id这类深层嵌套的属性值
  • 匹配逻辑错误:
    • 跨维度使用OR逻辑,不符合业务要求的「所有生效筛选条件同时满足」的AND规则
    • 单维度多值匹配时将查询条件拼接为字符串做包含判断,会出现大量非预期误匹配
  • 存在变量引用错误:自实现版本循环过滤时错误引用了作用域外的item变量

最终实现代码

首先实现一个通用的嵌套属性读取工具,支持点分隔的属性路径(比如props.id),不需要自定义特殊分隔符:

/**
 * 按路径读取嵌套对象属性值
 * @param obj 目标对象
 * @param path 点分隔的属性路径,例:"props.id"
 */
const getNestedValue = <T = unknown>(obj: Record<string, any>, path: string): T | undefined => {
  return path.split('.').reduce((current, key) => {
    if (current === null || current === undefined) return undefined
    return current[key]
  }, obj) as T
}

然后定义筛选配置类型和通用过滤函数:

interface FilterConfig<T> {
  // 待匹配的属性路径,支持嵌套写法
  path: string
  // 当前维度选中的值列表,空数组代表该维度不启用筛选
  selectedValues: Array<string | number>
}

/**
 * 通用多条件过滤函数
 * @param items 待过滤的原始数据数组
 * @param filterConfigs 筛选规则配置
 */
const genericFilter = <T extends Record<string, any>>(
  items: T[],
  filterConfigs: FilterConfig<T>[]
): T[] => {
  // 过滤出已启用的筛选规则(选中值非空的维度才参与判断)
  const activeFilters = filterConfigs.filter(config => config.selectedValues.length > 0)
  if (activeFilters.length === 0) return items

  return items.filter(item => {
    // 所有启用的筛选维度必须全部匹配(AND逻辑)
    return activeFilters.every(config => {
      const fieldValue = getNestedValue(item, config.path)
      return config.selectedValues.includes(fieldValue as string | number)
    })
  })
}

使用方式

对应提供的测试数据,调用方式如下,后续新增筛选维度只需要在配置数组中追加条目即可,不需要修改过滤函数核心逻辑:

// 数据结构定义
interface Item {
  description: string;
  name: string;
  props: {
    id: string
  }
}

// 筛选条件值
const selectedDrinks: string[] = ["cola", "fanta"]
const selectedIds: string[] = ["5", "4"]
// 后续新增筛选维度直接定义即可,例:const selectedNames: string[] = ["computer"]

const items: Item[] = [
  { description: "cola", name: "computer", props: { id: "4" } },
  { description: "fanta", name: "laptop", props: { id: "5" } },
  { description: "sprite", name: "phone", props: { id: "6" } }
]

// 执行过滤
const filterResult = genericFilter(items, [
  { path: "description", selectedValues: selectedDrinks },
  { path: "props.id", selectedValues: selectedIds },
  // 新增筛选维度直接加配置即可,空数组代表该维度暂不启用
  // { path: "name", selectedValues: selectedNames }
])

console.log(filterResult)
// 输出前两个条目:cola匹配id=4、fanta匹配id=5,均同时满足两个筛选维度的要求

实现特性

  • 零硬编码分支:新增任意筛选维度不需要修改过滤函数内部逻辑,扩展成本极低
  • 嵌套属性支持:采用通用的点分隔路径写法,读取深层属性不需要额外适配
  • 逻辑完全符合业务要求:
    • 跨维度为严格AND关系:所有启用的筛选条件必须同时匹配,条目才会被保留
    • 单维度内为OR关系:同一维度下选中多个值时,匹配任意一个值即判定该维度通过
    • 空选中值的维度自动跳过,不参与过滤逻辑
  • 类型安全:泛型实现保留TS类型推导,适配任意结构的条目数据

内容的提问来源于stack exchange,提问作者JamesG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 13:18:18