如何根据指定条件对象过滤JavaScript对象数组?现有代码无效
问题
我有一个JavaScript对象数组:
list = [ { id: 152956, appname: 'tst', approvalStatus: "Validated", children: [], clapp: {owner: '07D', code: 'TST', fullCLAPP: '07D/TST/G-PM'}, company: {id: 9705, name: 'Dot Com', code: '07D'}, connectionType: "", dnsNode: "", kind: "Standard", validatedOnce: true }, { id: 19876, appname: 'comptest', approvalStatus: "Validated", children: [], clapp: {owner: '07D', code: 'CMP', fullCLAPP: '07D/CMP/G-PM'}, company: {id: 765, name: 'IT jira', code: '07D'}, connectionType: "", dnsNode: "", kind: "Standard", validatedOnce: true } ]
需要根据以下条件对象进行过滤:
ob = {appname: 'airline', code: '07', company: {name:'abcd'}}
我尝试了下面的代码(包括改用if...else结构)但都没生效,请问怎么实现正确的过滤?
list.filter(data => Object.entries(ob).every(([k, v]) => typeof v === 'string'? data[k].toLowerCase().includes(v.toLowerCase()): typeof v ==='object'? Object.entries(v).every(([key ,value]) => data[k][key].toLowerCase().includes(value.toLowerCase())): data[k] === v));
问题分析与解决方案
你的代码失效主要有3个核心问题:
- 字段层级不匹配:条件对象中的
code是根级字段,但数组元素的code只存在于clapp或company子对象中,直接访问data['code']会得到undefined,调用toLowerCase()会直接报错。 - 缺失属性存在性检查:没有判断目标对象是否包含条件字段,一旦字段不存在就会触发错误。
- 过滤逻辑不符合实际需求:用
every意味着必须满足所有条件才会保留元素,但你的条件(比如appname: 'airline')和数组元素完全不匹配,自然返回空数组。
方案1:匹配所有条件(需修正条件结构或字段映射)
如果需要元素满足所有条件,先调整条件对象的结构(让字段层级和目标数组一致),再修正代码增加错误防护:
// 修正条件对象,让字段层级匹配数组元素 const ob = { appname: 'tst', company: { code: '07', name:'Dot Com' } }; const filteredList = list.filter(data => { return Object.entries(ob).every(([k, v]) => { // 检查当前层级字段是否存在 if (!data.hasOwnProperty(k)) return false; const dataValue = data[k]; if (typeof v === 'string') { // 确保目标值是字符串再做匹配 return typeof dataValue === 'string' && dataValue.toLowerCase().includes(v.toLowerCase()); } else if (typeof v === 'object' && v !== null) { // 处理嵌套对象,先检查目标值是否为对象 if (typeof dataValue !== 'object' || dataValue === null) return false; return Object.entries(v).every(([key, value]) => { if (!dataValue.hasOwnProperty(key)) return false; const nestedValue = dataValue[key]; return typeof nestedValue === 'string' && nestedValue.toLowerCase().includes(value.toLowerCase()); }); } // 非字符串/对象类型直接全等匹配 return dataValue === v; }); });
方案2:匹配任意一个条件
如果只要元素满足条件中的任意一项就保留,把every改为some,同时专门处理code字段的层级问题:
const filteredList = list.filter(data => { return Object.entries(ob).some(([k, v]) => { // 单独处理不在根层级的code字段 if (k === 'code') { const companyCode = data.company?.code || ''; const clappOwner = data.clapp?.owner || ''; return companyCode.toLowerCase().includes(v.toLowerCase()) || clappOwner.toLowerCase().includes(v.toLowerCase()); } // 处理其他根级字段 if (!data.hasOwnProperty(k)) return false; const dataValue = data[k]; if (typeof v === 'string') { return typeof dataValue === 'string' && dataValue.toLowerCase().includes(v.toLowerCase()); } else if (typeof v === 'object' && v !== null) { if (typeof dataValue !== 'object' || dataValue === null) return false; return Object.entries(v).some(([key, value]) => { if (!dataValue.hasOwnProperty(key)) return false; const nestedValue = dataValue[key]; return typeof nestedValue === 'string' && nestedValue.toLowerCase().includes(value.toLowerCase()); }); } return dataValue === v; }); });
这个方案会保留数组中所有company.code包含07的元素,也就是两个元素都会被筛选出来。
内容的提问来源于stack exchange,提问作者tasmia firdose
相关产品推荐
相关产品推荐

