我有一个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']}}
];
如果我选择 {' sex':['女性'男性']}&& {'饮食':[' flexitarian']} 输出应为 [' place2',& #39; 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 :(得分: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; });
最后,使用Underscore(比制作自己的更容易,因为我认为没有原生的JavaScript数组方法可用于...展平,从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"]
结果。
你绝对可以在matchingSet分配行中改进过滤器,以检查是否filterObj.sex不是真实的,只检查它是否是数组等长度检查,但为了保持简单......这个特殊的解决方案假设如果你不想在过滤器中饮食,那么就需要将空阵列作为饮食......
答案 1 :(得分: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>