如何在filter方法中遍历props实现联系人列表多属性筛选?
如何高效遍历包含嵌套对象的所有属性实现联系人筛选?
问题描述
我有一个用于筛选联系人列表的函数,逻辑是只要传入的属性中至少有一个与输入值匹配,该联系人就会被保留。目前仅实现了匹配姓名(名字+姓氏)的代码,想请教是否有高效方法可遍历所有props(包括含嵌套对象的props)实现该逻辑?
原代码如下:
handleSearch(event){ let CONTACTS = this.props.items; let inputValue = event.target.value; //dan var displayedUsers = CONTACTS.filter(el => { var searchValue = el.general.firstName + el.general.lastName; //this should be changed to el.allProps return searchValue.indexOf(inputValue) !== -1; // }); this.setState({displayedUsers: displayedUsers}); //will return dan, danone dante etc. }
解决方案
这个需求很常见,我给你提供一个高效的递归方案来解决——通过递归遍历对象的所有层级属性,一旦找到匹配内容就立刻终止遍历,避免不必要的计算。
步骤1:编写递归匹配辅助函数
这个函数可以处理字符串、嵌套对象甚至数组的情况,还做了大小写不敏感匹配(提升用户体验):
function hasMatch(obj, searchValue) { const lowerSearch = searchValue.toLowerCase(); // 当前值是字符串,直接检查是否包含搜索词 if (typeof obj === 'string') { return obj.toLowerCase().includes(lowerSearch); } // 遇到数组,遍历每个元素递归检查 if (Array.isArray(obj)) { for (const item of obj) { if (hasMatch(item, lowerSearch)) { return true; } } } // 遇到嵌套对象(非null),遍历自身属性递归检查 if (typeof obj === 'object' && obj !== null) { for (const key in obj) { if (obj.hasOwnProperty(key) && hasMatch(obj[key], lowerSearch)) { return true; } } } // 未找到匹配项 return false; }
步骤2:修改原筛选函数
把原来的姓名匹配逻辑替换成调用这个递归函数即可,还可以增加空输入的优化处理:
handleSearch(event) { const inputValue = event.target.value.trim(); // 输入为空时直接返回全部联系人,避免无效遍历 if (!inputValue) { this.setState({ displayedUsers: this.props.items }); return; } const displayedUsers = this.props.items.filter(el => hasMatch(el, inputValue)); this.setState({ displayedUsers }); }
额外优化说明
- 提前终止遍历:一旦找到匹配的属性值就立即返回
true,不用遍历完所有属性,大幅提升筛选效率 - 兼容数组属性:如果你的联系人数据里有数组类型的字段(比如
tags: ['同事', '朋友']),这个函数也能正确处理 - 空输入处理:用户清空搜索框时直接返回全量数据,避免不必要的计算
内容的提问来源于stack exchange,提问作者Гриша Кисенко
相关产品推荐
相关产品推荐

