React中如何搜索并过滤包含嵌套对象的数组?
如何在React中过滤嵌套对象的键或值
我在React应用里有一个展示JSON数据的数组,每个对象都包含fieldChange属性——这是个键值对不固定的嵌套对象。目前已经实现了对普通对象属性的搜索过滤,但不知道怎么实现对嵌套对象的键或值的过滤。
示例JSON数据
[ { "entity": "invalid", "timeStamp": "2022-09-12 05:57:12.397", "userId": 14, "source": "JeninReceiptValues", "action": "Update", "fieldChange": { "RecAmount": "553.0", "AppraisedBy": "5", "RecAmountNotes": "Found match in list. Deducted 33%./Set RecValue to 552.75" } }, { "entity": "valid", "timeStamp": "2022-09-12 05:57:13.600", "userId": 1180, "source": "RESON_UpdateCarBody", "action": "Create", "fieldChange": { "Body": "Sedan" } } ]
当前Search组件代码
const SearchBar = ({ logs, setSearch }) =>{ const handleSubmit =(e) => e.preventDefault() const handleSearchChange =(e) => { if (!e.target.value) return setSearch(logs) const value = e.taget.value const searchResult = logs.filter(log => log.source.toLowerCase().includes(value) || log.action.toLowerCase().includes(value) || log.entity.toLowerCase().includes(value)) setSearch(searchResult) } return( <header> <form onSubmit={handleSubmit}> <input className="search__input" type="text" id="search" onChange={handleSearchChange} /> </form> </header> ) } export default SearchBar
我的尝试及结果
我试过这段代码:
console.log(logs.filter( log => { return Object.values(log.fieldChange).flat(y=>log===(//---(e.target.value)---'Sedan')) }) )
得到的输出是:
map (12) [Array(0), Array(1), Array(0), Array(0), Array(0), Array(1), Array(0), Array(0), Array(0), Array(1), Array(0), Array(0)] 0 : [] 1 : ['Sedan'] 2 : [] 3.......
解决方案
核心思路
要过滤fieldChange的键或值,需要遍历这个嵌套对象的所有键值对,检查是否包含搜索关键词。我们可以把匹配逻辑拆分为普通属性匹配和嵌套对象匹配,最后合并两个条件。
修改后的完整代码
const SearchBar = ({ logs, setSearch }) =>{ const handleSubmit =(e) => e.preventDefault() const handleSearchChange =(e) => { if (!e.target.value) return setSearch(logs) // 统一转小写,实现大小写不敏感搜索 const searchValue = e.target.value.toLowerCase() const searchResult = logs.filter(log => { // 1. 普通属性的匹配逻辑(保留原有逻辑,可按需添加更多字段) const matchesBasic = log.source.toLowerCase().includes(searchValue) || log.action.toLowerCase().includes(searchValue) || log.entity.toLowerCase().includes(searchValue) || log.timeStamp.toLowerCase().includes(searchValue) // 2. 嵌套对象fieldChange的匹配逻辑:检查键或值是否包含关键词 const matchesNested = Object.entries(log.fieldChange).some(([key, value]) => { // 值可能是数字等非字符串类型,先转成字符串再判断 return key.toLowerCase().includes(searchValue) || value.toString().toLowerCase().includes(searchValue) }) // 满足任意一个条件就保留该条数据 return matchesBasic || matchesNested }) setSearch(searchResult) } return( <header> <form onSubmit={handleSubmit}> <input className="search__input" type="text" id="search" onChange={handleSearchChange} placeholder="搜索内容..." /> </form> </header> ) } export default SearchBar
关键细节说明
- 修正笔误:原代码里的
e.taget.value是拼写错误,改为e.target.value。 - 大小写统一:把搜索关键词和所有匹配字段都转成小写,避免大小写导致的匹配失败。
- 遍历嵌套对象:用
Object.entries()把fieldChange转成[键, 值]的数组,方便同时检查键和值。 some()方法的妙用:some()会遍历数组,只要有一个元素满足条件就返回true,效率比遍历全部元素更高。- 值类型兼容:把
value转成字符串(value.toString()),避免遇到数字等非字符串类型时出现错误。
为什么之前的尝试失败?
你之前用Object.values().flat()的思路不对:flat()是用来扁平化多维数组的,不是用来做匹配判断的,而且你的条件判断逻辑也没有正确检查值是否包含关键词。用Object.entries()配合some()才是更直接高效的方式。
内容的提问来源于stack exchange,提问作者Naftalib
相关产品推荐
相关产品推荐

