我有一个react live search下拉组件,该组件按搜索词过滤对象数组。它按标题过滤我的对象,然后返回所有相关对象的列表。这很好。
当前
:数据结构
data: [
{ id: 1, title: 'Some title here' },
{ id: 2, title: 'Another title' },
{ id: 3, title: 'last title' },
]
组件
<LiveSearch
term={term}
data={data} />
内部实时搜索组件
按字词和呈现列表过滤数据
return data
.filter(item => item.title.toLowerCase().includes(term.toLowerCase())
.map((item, idx) => <li key={idx}>{item.title}</li>
我要搜索的对象变得越来越高级,我想做的是将要与搜索词进行比较的一组属性名称传递给我的组件。
我背后的思维过程是遍历对象属性,如果其中一个属性与术语相匹配,则循环中断并返回true,将该对象添加到要显示的项目列表中。
目标
数据结构
data: [
{ id: 1, country: 'Canada', title: 'Some title here' },
{ id: 2, country: 'Australia', title: 'Another title' },
{ id: 3, country: 'Netherlands', title: 'last title' },
]
组件
<LiveSearch
searchFields={['country', 'title']}
term={term}
data={data} />
内部组件过滤
return data
.filter(item => {
// Dynamic filtering of terms here
})
.map((item, idx) => <li key={idx}>{item.title}</li>
在过滤器内部,我试图遍历数组并动态生成与此类似的逻辑
item.searchFields[0].toLowerCase().includes(term.toLowerCase()) ||
item.searchFields[1].toLowerCase().includes(term.toLowerCase())
但是显然可以遍历无限数量的搜索字段/属性
答案 0 :(得分:1)
类似
term = term.toLowerCase()
return data
.filter(item => {
return searchFields.some(field => item[field].toLowerCase().includes(term))
}).map(...
答案 1 :(得分:1)
检查some
中的searchFields
是否匹配:
// Checks wether a value matches a term
const matches = (value, term) => value.toLowerCase().includes(term.toLowerCase());
// Checks wether one of the fields in the item matcues the term
const itemMatches = (fields, term) => item => fields.some(field => matches(item[field], term);
// Filter the data to only contain items where on of the searchFields matches the term
const result = props.data.filter( itemMatches(props.searchFields, props.term) );
return result.map(item => <li key={idx}>{item.title}</li>);
答案 2 :(得分:1)
您可以将数组.some
与.filter
组合使用
let result = data.filter(obj =>
searchFields.some(s =>
obj[s] != undefined && obj[s].toLowerCase() === term
));
let data = [
{ id: 1, country: 'Canada', title: 'Some title here' },
{ id: 2, country: 'Australia', title: 'Another title' },
{ id: 3, country: 'Netherlands', title: 'last title' },
], searchFields = ["country", "title"], term = "canada";
let result = data.filter(obj =>
searchFields.some(s =>
obj[s] != undefined && obj[s].toLowerCase() === term
));
console.log(result);