Задать вопрос
640
@640
Beginner

Как сделать фильтрацию по нескольким параметрам?

Есть массив объектов:

data = [
  { bg: 'black', color: 'green' },
  { bg: 'black', color: 'green' },
  { bg: 'black', color: 'red' },
  { bg: 'black', color: 'red' },

  { bg: 'white', color: 'green' },
  { bg: 'white', color: 'green' },
  { bg: 'white', color: 'red' },
  { bg: 'white', color: 'red' }
 
]

И есть два фильтра:

5cc227bf6b950185290186.jpeg
Когда выбран первый фильтр, например background black, выводится только:

[
  { bg: 'black', color: 'green' },
  { bg: 'black', color: 'green' },
  { bg: 'black', color: 'red' },
  { bg: 'black', color: 'red' }
]

И когда к этому добавляется ещё один фильтр, например color red, оно, соответственно, выдаст:

[
  { bg: 'black', color: 'red' },
  { bg: 'black', color: 'red' }
]

Как это реализовать?

Фильтры я устанавливаю в примерно таком объекте:

filters = {
  bg: 'white', // or 'none', or 'black'
  color: 'none', // or 'red, or 'green'
}
  • Вопрос задан
  • 275 просмотров
Подписаться 1 Средний Комментировать
Решения вопроса 1
0xD34F
@0xD34F Куратор тега React
Положить в стейт фильтры - массив объектов, содержащих имя свойства, по которому выполняется фильтрация, текущее значение, массив значений, доступных для выбора:

filters: [
  { field: 'bg', value: '', options: [ 'black', 'white' ] },
  { field: 'color', value: '', options: [ 'red', 'green' ] },
],

На основе этого массива создать элементы фильтров:

filters.map((n, i) => (
  <label>
    {n.field}:
    <select data-index={i} onChange={this.onChange}>
      <option value="">none</option>
      {n.options.map(n => <option>{n}</option>)}
    </select>
  </label>
))

onChange = e => {
  const index = +e.target.dataset.index;
  const value = e.target.value;

  this.setState(prevState => ({
    filters: prevState.filters.map((n, i) => index === i ? { ...n, value } : n)
  }));
}

Получить отфильтрованные данные:

const filteredData = filters.reduce((acc, n) => {
  return n.value
    ? acc.filter(m => m[n.field].includes(n.value))
    : acc;
}, data);

Вместо полных данных отобразить отфильтрованные.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@dohera
Фронтенд разработчик
const filterColor = chosedColor => currColor => chosedColor === 'none' ? true : currColor === chosedColor
arr.filter(filterColor(inputValue1)).filter(filterColor(inputValue2))

примерно так
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы