2015-04-04 64 views
2

我有一個Javascript數組:如何動態過濾對象?

var peoples = [ 
{'people':{'sex':'male', 'diet':'vegetarian','favPlaces':['place1','place2']}}, 
{'people':{'sex':'female', 'diet':'flexitarian','favPlaces':['place2','place3']}}, 
{'people':{'sex':'male', 'diet':'flexitarian', 'favPlaces':['place4','place1']}} 
]; 

如果我選擇{ '性':[ '女', '男性']} & & { '飲食':[ 'flexitarian']}輸出應該是['place2','place3','place4','place1']

到我的代碼的問題是,如果我只能選擇「性」它不會顯示的結果,但如果我選擇既是「性」「飲食」它會顯示結果。 我無法弄清楚如何讓我的代碼具有動態性,這樣當我選擇性別或飲食,性別和飲食時,代碼就會動態過濾,並且會顯示結果。

這是我的代碼:

var filterObj = {'sex': ['female', 'male'], 'diet': ['flexitarian']}; 

    for(var p in peoples){ 
     for(var s in filterObj.sex){ 
      for(var d in filterObj.diet){ 
      if((filterObj.sex[s] == peoples[p].people.sex) && (filterObj.diet[d] == peoples[p].people.diet)){ 
      console.log(peoples[p].people.favPlaces); 
      } 
     } 
    } 

這是HTML:

<ul id="sex"> 
<li><label><input type="checkbox" value="male">Male</label></li> 
<li><label><input type="checkbox" value="female">Female</label></li> 
</ul> 
<ul id="diet"> 
<li><label><input type="checkbox" value="none">None</label></li> 
<li><label><input type="checkbox" value="flexitarian">Flexitarian</label></li> 
<li><label><input type="checkbox" value="vegetarian">Vegetarian</label></li> 
</ul> 
+0

你不需要'新的對象()'那裏,它可以安全刪除。只保留內容。 – SeinopSys 2015-04-04 11:37:51

+0

請看看這個[SO回答](http://stackoverflow.com/questions/28354252/trouble-with-math-in-javascript-when-elements-clicked/28355096#28355096)。我認爲Underscore'filter'方法也適用於你。 – AWolf 2015-04-04 11:49:33

+0

@ DJDavid98,謝謝。 – Gen 2015-04-04 11:57:04

回答

1

您可以使用Array.indexOf和反轉的條件,如...檢查,如果個人數據如果沒有任何內容(通過檢查它的長度),如下所示,也可以忽略過濾器...

var matchingSet = peoples.filter(function(p) { 
    return (filterObj.sex.length === 0 || filterObj.sex.indexOf(p.people.sex) !== -1)  //peoples' sex must exists in the filter.sex or ignore it if filter not specified 
    && (filterObj.diet.length === 0 || filterObj.diet.indexOf(p.people.diet) !== -1);  //and people's diet must exists in the filter.diet or ignore it if filter not specified 
}); 

然後,使用Array.map將favPlaces拉出匹配集。

var matchingPlaces = matchingSet.map(function(p) { return p.people.favPlaces; }); 

最後,使用下劃線(不是使自己更容易,因爲我認爲這個沒有本地JavaScript Array方法尚未...拉平,從favPlaces陣列中提取獨特的價值觀和排序它(如額外獎金):

var flatten = _.chain(matchingPlaces) 
    .flatten() 
    .uniq() 
    .sortBy(function(p) { return p; }) 
    .value(); 

這將產生你,你正在尋找的結果

["place1","place2","place3","place4"] 

完整的示例,可以發現:http://jsfiddle.net/rdfyp5c9/2/

注意,在例子中,我除去飲食過濾元件:

var filterObj = { 
    'sex' : ['male'], 
    'diet': [] 
}; 

和其被正確地返回

["place1","place2","place4"] 

爲結果。

如果filterObj.sex不是真的,只能執行長度檢查,如果它是數組等等,你可以在匹配集賦值行中明確地細化過濾器,以檢查是否存在這個特定的解決方案假設如果你不想在過濾器中飲食,那麼需要通過空陣列作爲飲食......

+0

這正是我要找的!謝謝 – Gen 2015-04-04 12:58:40

0

使用開源項目jinqJs應該很容易

var peoples = [ 
 
{'people':{'sex':'male', 'diet':'vegetarian','favPlaces':['place1','place2']}}, 
 
{'people':{'sex':'female', 'diet':'flexitarian','favPlaces':['place2','place3']}}, 
 
{'people':{'sex':'male', 'diet':'flexitarian', 'favPlaces':['place4','place1']}} 
 
]; 
 

 
var result = jinqJs().from(peoples).where(function(row){return (row.people.sex === 'female' || row.people.diet === 'flexitarian');}).select(function(row){return row.people.favPlaces;}); 
 

 
document.body.innerHTML = '<pre>' + JSON.stringify(result, null, 4) + '</pre><br><br>';
<script src="https://rawgit.com/fordth/jinqJs/master/jinqjs.js"></script>