繁体   English   中英

按对象属性动态过滤数组

[英]Dynamic array filtering by object property

我有一个反应实时搜索下拉组件,该组件按搜索词过滤对象数组。 它按标题过滤我的对象,然后返回所有相关对象的列表。 这很好。

当前:

数据结构

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())

但显然可以遍历无限数量的搜索字段/属性

使用Array#some()

就像是

term = term.toLowerCase()
return data
  .filter(item => {
    return searchFields.some(field => item[field].toLowerCase().includes(term))
  }).map(...

检查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>);

您可以将Array .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); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM