具有多种条件的数组过滤javascript

时间:2018-09-26 14:25:38

标签: javascript

我不知道如何过滤具有多个条件的数组。我有一个带有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) {
    // ??
  });

Screenshot

用户选择对酒店的要求,他应该获得符合所有要求的酒店。而且,如果其中一些未选中,则默认情况下不会计入它们。

5 个答案:

答案 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 &gt;= <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;
};