按对象属性进行动态数组过滤

时间:2018-11-14 17:36:53

标签: javascript arrays filter

我有一个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())

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

3 个答案:

答案 0 :(得分:1)

使用Array#some()

类似

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