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

通用JavaScript实现:基于任意层级属性过滤对象数组

如何通用地基于任意层级属性过滤对象列表(未知属性名称)

问题分析

你遇到的核心问题是嵌套对象的属性匹配:直接用Object.keys()遍历第一层属性时,没法处理过滤条件里的深层嵌套(比如address.zip),而且对象是引用类型,直接比较整个子对象肯定不相等,得逐个检查嵌套里的每个属性。

解决方案:递归匹配过滤条件

我们可以写一个递归辅助函数,用来检查单个对象是否满足所有层级的过滤条件,再结合数组的filter()方法实现列表过滤。

1. 递归匹配函数

这个函数会遍历过滤条件的每个属性,遇到嵌套对象就递归检查下一层:

function matchesFilter(obj, filterObj) {
  // 遍历过滤条件的每一个属性键
  for (const key of Object.keys(filterObj)) {
    const filterVal = filterObj[key];
    const objVal = obj[key];

    // 如果过滤值是对象(且不是null),递归检查下一层级
    if (typeof filterVal === 'object' && filterVal !== null) {
      // 目标对象没有对应属性,或者递归检查不通过,直接返回不匹配
      if (!objVal || !matchesFilter(objVal, filterVal)) {
        return false;
      }
    } else {
      // 非对象类型,直接比较值是否相等
      if (objVal !== filterVal) {
        return false;
      }
    }
  }
  // 所有过滤条件都满足,返回匹配
  return true;
}

2. 应用到列表过滤

用上面的辅助函数配合Array.filter(),就能轻松过滤你的对象列表:

var list = [ 
  { name: 'Alice', address: { zip: '10000', street: '71 Pilgrim Avenue' } }, 
  { name: 'Bob', address: { zip: '20000', street: '44 Shirley Ave' } }, 
  { name: 'Charlie', address: { zip: '30000', street: '4 Goldfield Rd' } },
];
var filter = { address: { zip: '10000' } };

// 执行过滤
const filteredResult = list.filter(item => matchesFilter(item, filter));
console.log(filteredResult);

运行后会得到你期望的结果:

[{ name: 'Alice', address: { zip: '10000', street: '71 Pilgrim Avenue' } }]

扩展测试:多属性多层级过滤

这个方案支持更复杂的过滤条件,比如同时匹配name和深层的street:

var complexFilter = { name: 'Bob', address: { street: '44 Shirley Ave' } };
const complexResult = list.filter(item => matchesFilter(item, complexFilter));
// 输出: [{ name: 'Bob', address: { zip: '20000', street: '44 Shirley Ave' } }]

为什么你之前的方法有问题?

你提到用Object.keys()时遇到属性值以数组形式返回?应该是没处理嵌套对象的情况:比如直接拿到filter.address后,直接和item.address比较——但两个对象是不同的引用,即使内容一样也会返回false。而递归函数会逐个检查嵌套里的每个属性值,就能正确匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:27:05