我不知道如何过滤具有多个条件的数组。我有一个带有2个select,1个复选框字段集和1个单选按钮字段集的搜索过滤器表单。我具有返回符合所选条件的项目的函数。它们仅单独工作。查找符合所有条件的对象的最佳方法是什么?
我试图为所有可能的选项制作if语句,但是代码无法正常工作,并且看来应该有一些更好的选择。
以下是函数示例:
function chooseRating(hotel) {
return hotel.rating == e.target.value;
}
function chooseMeal(hotel) {
return hotel.mealType == e.target.value;
}
function choosePlace(hotel) {
for (let l = 0; l < chosenPlace.length; l++) {
if(chosenPlace[l].checked) {
return hotel.region == e.target.value;
}
}
}
我该如何过滤数组?
let filteredCards = hotels.filter(function(hotel, index, hotels) {
// ??
});
用户选择对酒店的要求,他应该获得符合所有要求的酒店。而且,如果其中一些未选中,则默认情况下不会计入它们。
答案 0 :(得分:1)
我必须使用2个输入对代码挑战进行过滤。
您所说的我的第一种方法是在一个过滤器中编写if条件,并且不起作用。
我要做的是根据第一个条件创建一个新的数组过滤,然后使用第二个条件过滤返回的数组,并且该数组起作用了。
希望这可以解决您的问题:D
答案 1 :(得分:1)
所以可以说你有这样的东西:
<select id="rating">Rating options here ...</select>
<select id="meals">Meals options here ...</select>
<fieldset id="places">
<input type="checkbox" value="one">place one</input>
<input type="checkbox" value="two">place two</input>
</fieldset>
<input type="radio" name="rad" value="rad_one">radio one</input>
<input type="radio" name="rad" value="rad_two">radio two</input>
您可以使用以下方式过滤酒店数组:
let selected_rating = document.querySelector('#rating').value;
let selected_meal = document.querySelector('#meals').value;
let selected_places = [].map.call(document.querySelectorAll('#places input[type="checkbox"]:checked'),function(elem){ return elem.value});
let selected_radio = document.querySelector('[name="rad"]:checked').value;
let filteredCards = hotels.filter(function(hotel){
return hotel.rating == selected_rating
&& hotel.mealType == selected_meal
&& selected_places.indexOf(hotel.place) != -1
&& hotel.region == selected_radio;
});
答案 2 :(得分:1)
您可以像这样链接您的filter()
通话:
// first filter
function filterRating(hotel) {
return hotel.rating >= filters.rating;
}
// second filter
function filterMeal(hotel) {
return !filters.mealType.length || hotel.mealType == filters.mealType;
}
// apply both filters to initial array
function update() {
let filteredCards = hotels.filter(filterRating).filter(filterMeal);
};
完整示例:
var filters = {
rating: 4,
mealType: ""
};
rating.value = filters.rating;
mealtype.value = filters.mealType;
rating.addEventListener("input", function() {
filters.rating = rating.value;
update();
});
mealtype.addEventListener("input", function() {
filters.mealType = mealtype.value;
update();
});
function filterRating(hotel) {
return hotel.rating >= filters.rating;
}
function filterMeal(hotel) {
return !filters.mealType.length || hotel.mealType == filters.mealType;
}
function update() {
let filteredCards = getHotels().filter(filterRating).filter(filterMeal);
console.log(filters);
output.innerHTML = filteredCards.map(hotel => `<span>${hotel.name}</span>`).join("");
};
update();
function getHotels() {
return [{
name: "A",
rating: 5,
mealType: "full"
},
{
name: "B",
rating: 4,
mealType: "full"
},
{
name: "C",
rating: 4,
mealType: "breakfast"
},
{
name: "D",
rating: 5,
mealType: "breakfast"
}
];
}
input,
select {
margin: 1em 0
}
#rating {
width: 3em
}
#output span {
display: inline-block;
border: 1px solid black;
padding: 0.5em;
margin: 0.5em;
}
Rating >= <input id="rating" value="5" type="number"><br> Meal:
<select id="mealtype">
<option value="">any</option>
<option>breakfast</option>
<option>full</option>
</select><br>
<p id="output"></p>
答案 3 :(得分:0)
如果我已正确理解问题,则可以将所有匹配函数传递给filter()
测试函数,并使用AND运算符要求它们全部为真:
let filteredCards = hotels.filter(hotel => chooseRating(hotel) && chooseMeal(hotel) && choosePlace(hotel))
这与:
let filteredCards = hotels.filter(hotel => {
return chooseRating(hotel) && chooseMeal(hotel) && choosePlace(hotel)
})
这也是相同的:
let filteredCards = hotels.filter(function(hotel) {
return chooseRating(hotel) && chooseMeal(hotel) && choosePlace(hotel)
})
答案 4 :(得分:0)
简洁实用的解决方案
const combineFilters = (...filters) => (item) => {
return filters.map((filter) => filter(item)).every((x) => x === true);
};
然后你就这样使用它:
const filteredArray = arr.filter(combineFilters(filterFunc1, filterFunc2));
和 filterFunc1 例如可能看起来像这样:
const filterFunc1 = (item) => {
return item === 1 ? true : false;
};