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

TypeScript改造数组过滤方法 实现多条件同时匹配返回对应对象

对象数组多筛选值全匹配过滤实现

现有逻辑说明

现有测试数据:

arr = [
  {name: "tom", tools:["spanner", "hammer", "screwdriver"]}, 
  {name: "john", tools:["Mallet", "hammer", "screwdriver"]},
  {name: "phil", tools:["Mallet", "Drill", "screwdriver"]}
]

原有过滤方法:

private filterObjectArray(arr: any, filterArr: any): any {
  return arr.filter((el: any) =>
    filterArr.some(
      (f: any) =>
        el.tools.toString()?.toLowerCase().indexOf(f.name?.toLowerCase()) >= 0
    )
  );
 }

原方法基于Array.some()实现任意匹配逻辑:传入筛选参数filterArr = [{name: "screwdriver"}, {name: "hammer"}]时,只要元素的tools属性包含任意一个筛选值就会被返回。由于三个元素都包含screwdriver,最终全部被命中,不符合要求。
需求是调整为全匹配逻辑:仅当对象的tools属性同时包含filterArr中所有筛选值时才返回,上述筛选条件下,应仅返回同时持有screwdriver和hammer的tom、john,仅持有screwdriver的phil需要被排除。

实现代码

核心改动两点:

  • 把匹配判断从some()(任意项满足即通过)替换为every()(所有项都满足才通过)
  • 废弃原有的toString()转字符串匹配的写法,避免子串误判(比如筛选hammer时错误匹配到包含jackhammer的条目),转用Set做存在性校验,准确率和性能都更好。

修改后的完整方法:

private filterObjectArray(arr: any[], filterArr: Array<{name: string}>): any[] {
  // 提前统一处理筛选值为小写,过滤空值,避免循环内重复计算
  const validFilterValues = filterArr
    .map(item => item.name?.toLowerCase())
    .filter(Boolean);

  return arr.filter(element => {
    // 将当前元素的工具列表统一转小写存入Set,做存在性判断效率更高
    const lowerToolSet = new Set(
      element.tools.map((tool: string) => tool.toLowerCase())
    );
    // 必须所有筛选值都在工具列表中存在,才保留当前元素
    return validFilterValues.every(filterVal => lowerToolSet.has(filterVal));
  });
}

效果验证

传入筛选参数[{name: "screwdriver"}, {name: "hammer"}]时:

  • tom的工具列表包含两个筛选值,保留
  • john的工具列表包含两个筛选值,保留
  • phil的工具列表仅包含screwdriver,缺少hammer,被过滤
    完全符合预期。

可选适配:如果业务要求传入空筛选数组时返回空结果,只需要在方法最开头加一行判断即可:if (validFilterValues.length === 0) return []

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 04:09:25