2017-06-01 112 views
2

我想知道什么是最干净的方式,根据string keyword筛选对象数组的更好方法。搜索必须在对象的任何属性中进行。任何属性包含值的对象的过滤器数组

当我打字lea我想要走线槽中的所有对象及其所有属性可以返回包含lea

当我打字italy我想要走线槽中的所有对象及其所有属性返回的对象包含italy的对象。

我知道很多解决方案,但到目前为止我只看到了一些你需要指定你想要匹配的属性。

ES6 and lodash are welcome!

const arrayOfObject = [{ 
 
     name: 'Paul', 
 
     country: 'Canada', 
 
    }, { 
 
     name: 'Lea', 
 
     country: 'Italy', 
 
    }, { 
 
     name: 'John', 
 
     country: 'Italy', 
 
    }, ]; 
 

 
    filterByValue(arrayOfObject, 'lea') // => [{name: 'Lea',country: 'Italy'}] 
 
    filterByValue(arrayOfObject, 'ita') // => [{name: 'Lea',country: 'Italy'}, {name: 'John',country: 'Italy'}]

+0

青睐现场堆网页摘要过异地服务,如的jsfiddle。 –

回答

3

你可以将其过滤和搜索只是为搜索字符串的一个occurence。

方法使用:

function filterByValue(array, string) { 
 
    return array.filter(o => 
 
     Object.keys(o).some(k => o[k].toLowerCase().includes(string.toLowerCase()))); 
 
} 
 

 
const arrayOfObject = [{ name: 'Paul', country: 'Canada', }, { name: 'Lea', country: 'Italy', }, { name: 'John', country: 'Italy' }]; 
 

 
console.log(filterByValue(arrayOfObject, 'lea')); // [{name: 'Lea', country: 'Italy'}] 
 
console.log(filterByValue(arrayOfObject, 'ita')); // [{name: 'Lea', country: 'Italy'}, {name: 'John', country: 'Italy'}]
.as-console-wrapper { max-height: 100% !important; top: 0; }

+0

我喜欢这个。看起来很清楚。 –

+0

如果其中一个属性不是一个字符串,而是一个对象,我们可能希望使用此函数filterByValue(array,string)返回array.filter(o => {0} {0}返回Object.keys(o).some如果(typeof o [k] ==='string')return o [k] .toLowerCase().include(string.toLowerCase()); }); }); }' –

+2

你可以在没有if语句的情况下缩短它,并返回typeof o [k] ==='string'&& o [k] .toLowerCase()。includes(string.toLowerCase());' –

3

使用Object.keys遍历所述对象的属性。使用缩小和过滤器以使代码更高效:

const results = arrayOfObject.filter((obj)=>{ 
    return Object.keys(obj).reduce((acc, curr)=>{ 
      return acc || obj[curr].toLowerCase().includes(term); 
    }, false); 
}); 

其中term是您的搜索条件。

+1

几乎要评论这个了!干净的答案。 – DrunkDevKek

+0

我需要开始使用'reduce()'-_- ;;; –

+1

这里不需要减少。 –

0

您始终可以使用array.filter(),然后遍历每个对象,并且如果有任何值与您正在查找的值匹配,则返回该对象。

const arrayOfObject = [{ 
 
     name: 'Paul', 
 
     country: 'Canada', 
 
    }, { 
 
     name: 'Lea', 
 
     country: 'Italy', 
 
    }, { 
 
     name: 'John', 
 
     country: 'Italy', 
 
    }, ]; 
 
    
 
let lea = arrayOfObject.filter(function(obj){ 
 
    //loop through each object 
 
    for(key in obj){ 
 
    //check if object value contains value you are looking for 
 
    if(obj[key].includes('Lea')){ 
 
     //add this object to the filtered array 
 
     return obj; 
 
     } 
 
    } 
 
    }); 
 
     
 
console.log(lea);

0

function filterByValue(arrayOfObject,words){ 
 
    let reg = new RegExp(words,'i'); 
 
    return arrayOfObject.filter((item)=>{ 
 
    let flag = false; 
 
    for(prop in item){ 
 
     if(reg.test(prop)){ 
 
      flag = true; 
 
     } 
 
    } 
 
    return flag; 
 
    }); 
 
}

3

那么,当我们已经知道,它不是要和方法的对象上的搜索,我们可以做以下节省时间复杂度:

function filterByValue(array, value) { 
    return array.filter((data) => JSON.stringify(data).toLowerCase().indexOf(value.toLowerCase()) !== -1); 
} 
+0

This也会在对象的键上找到搜索关键字,但OP可能只是想仅搜索值。 – dopeddude

+1

是的,这可以避免使用正则表达式。这里的想法是消除对象的按键循环 – binariedMe

0

一种方法是使用如下的Array#filter,String#toLowerCaseString#indexOf

const arrayOfObject = [{ 
 
      name: 'Paul', 
 
      country: 'Canada', 
 
     }, { 
 
      name: 'Lea', 
 
      country: 'Italy', 
 
     }, { 
 
      name: 'John', 
 
      country: 'Italy', 
 
     }]; 
 

 
     function filterByValue(arrayOfObject, term) { 
 
      var ans = arrayOfObject.filter(function(v,i) { 
 
       if(v.name.toLowerCase().indexOf(term) >=0 || v.country.toLowerCase().indexOf(term) >=0) { 
 
        return true; 
 
       } else false; 
 
      }); 
 
      console.log(ans); 
 
     } 
 
     filterByValue(arrayOfObject, 'ita');

0

这是我会怎么使用lodash做到这一点:

const filterByValue = (coll, value) => 
    _.filter(coll, _.flow(
    _.values, 
    _.partialRight(_.some, _.method('match', new RegExp(value, 'i'))) 
)); 

filterByValue(arrayOfObject, 'lea'); 
filterByValue(arrayOfObject, 'ita'); 
相关问题