2017-06-01 129 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'); 
相關問題