如何在React中实现数组及嵌套数组的多条件过滤?
问题翻译
我想在同一个函数里实现对数组及其内部嵌套数组的过滤。目前针对keysFirst和keysSecond的过滤功能已经正常工作。人员数组包含skills和roles两个嵌套数组,其中skills数组有name和stars属性,我需要基于name属性进行过滤。请问怎么编写一个函数,能同时对keysFirst和/或keysSecond,以及一个或两个嵌套数组进行过滤?以下是Homepage.jsx中的代码:
const [queryText, setQuery] = useState(""); const [querySecond, setQuerySecond] = useState(""); const [queryThird, setQueryThird] = useState(""); const keysFirst = ["firstname", "lastname"]; const keysSecond = ["location", "department"]; const keysThird = ["skills", "roles"]; const [data, setData] = useState([ { firstname: "Brad", lastname: "Pitt", location: "America", department: "Hollywood", skills: [ { name: "Actor", stars: 5 }, { name: "Fighting", stars: 4 }, ], roles: [ { name: "Snatch", salary: 1000 }, { name: "Fightclub", salary: 2000 }, ], }, { firstname: "Jason", lastname: "Statham", location: "England", department: "Hollywood", skills: [ { name: "Driving", stars: 2 }, { name: "Taxi", stars: 4 }, ], roles: [ { name: "Crank", salary: 3000 }, { name: "Transporter 2", salary: 4000 }, ], }, ]); const searchFunction = (data) => { const personFiltered = data.filter( (item) => keysFirst.some((keysFirst) => item[keysFirst].toLowerCase().includes(queryText.toLowerCase()) ) && keysSecond.some((keysSecond) => item[keysSecond].toLowerCase().includes(querySecond.toLowerCase()) ) ); return personFiltered; };
解决方案
修改searchFunction,加入嵌套数组的过滤逻辑,同时处理空查询的边界情况(避免空输入时过滤掉所有数据):
const searchFunction = (data) => { // 统一转小写,避免大小写敏感,且只转一次提升性能 const lowerQueryText = queryText.toLowerCase(); const lowerQuerySecond = querySecond.toLowerCase(); const lowerQueryThird = queryThird.toLowerCase(); return data.filter(item => { // 顶层属性keysFirst过滤:空查询直接满足 const matchesFirst = lowerQueryText === "" ? true : keysFirst.some(key => item[key].toLowerCase().includes(lowerQueryText)); // 顶层属性keysSecond过滤:逻辑同上 const matchesSecond = lowerQuerySecond === "" ? true : keysSecond.some(key => item[key].toLowerCase().includes(lowerQuerySecond)); // 嵌套数组过滤:检查skills/roles的name属性,空查询直接满足 const matchesNested = lowerQueryThird === "" ? true : keysThird.some(nestedKey => item[nestedKey].some(nestedItem => nestedItem.name.toLowerCase().includes(lowerQueryThird) ) ); // 三个条件同时满足(空查询的条件自动生效) return matchesFirst && matchesSecond && matchesNested; }); };
逻辑说明
- 所有查询文本预先转小写,避免大小写匹配问题,同时减少重复转换的性能消耗
- 每个过滤分支都做了空值判断:如果对应的查询输入为空,直接返回
true,相当于跳过该条件的过滤 - 嵌套数组过滤通过双层
some实现:先遍历keysThird中的嵌套数组字段,再遍历每个嵌套数组内的元素,检查name属性是否匹配查询文本 - 最终返回同时满足所有非空查询条件的人员数据,支持单独或组合使用任意过滤条件
内容的提问来源于stack exchange,提问作者Alexander Simonsen
相关产品推荐
相关产品推荐

