Chefranov
@Chefranov
Новичок

Как оптимизировать множественный фильтр?

Имеется вот такая панель расширенного поиска:

5d28b33d90543127344302.jpeg
В секции computed у меня на данный момент фильтруется след. способом (еще не все фильтры есть):

computed: {
    filteredItems() {
      if (this.activeFilter && this.activeFilter != 'all') {
        return this.items[this.activeFilter]
          .filter(item => item.name.toLowerCase().indexOf(this.search.toLowerCase()) !== -1)
          .filter(item => item.itemLevel >= this.minLvl && item.itemLevel <= this.maxLvl);
      } else {
        let all = [];
        let i;
        if (this.items) {
          for (i = 0; i < this.filters.length; i++) {
            Array.prototype.push.apply(all, this.items[this.filters[i].value]);
          }
        }
        return all
          .filter(item => item.name.toLowerCase().indexOf(this.search.toLowerCase()) !== -1)
          .filter(item => {
            if (this.minLvl !== '' && this.maxLvl !== '') {
              if (item.itemLevel >= this.minLvl && item.itemLevel <= this.maxLvl) return true;
            } else if (this.minLvl == '' && this.maxLvl !== '') {
              if (item.itemLevel <= this.maxLvl) return true;
            } else if (this.minLvl !== '' && this.maxLvl == '') {
              if (item.itemLevel >= this.minLvl) return true;
            } else {
              return true;
            }
          });
      }
    },
  }

Фильтров может использоваться несколько одновременно. Если ничего из фильтров не заполнено, то выводит все итемы.
Ну и вопрос в следующем, как можно это всё сократить/оптимизировать? Я думал может вынести в функцию и параметры передавать, но мне кажется все равно много кода выйдет.
  • Вопрос задан
  • 174 просмотра
Решения вопроса 1
@VasilyBykov
Каждый фильтр выделить в отдельный computed, который возвращает функцию или null.
Ещё один computed массива фильтров.
И уже этот массив фильтров применять.
computed: {
  filterA() {
    return this.a !== '' ? item => item.propA === this.a : null;
  },
  filterB() {
    return this.b !== '' ? item => item.propB === this.b : null;
  },
  filters() {
    return [this.filterA, this.filterB].filter(Boolean);
  }, 
  filteredItems() {
    return this.filters.length 
      ? this.items.filter(item => this.filters.every(f => f(item))
      : this.items;
  } 
}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
Robur
@Robur
Знаю больше чем это необходимо
Кода у вас выйдет столько сколько надо для реализации логики, сократить до пары строчек у вас все равно не получится, можно только немного сократить/организовать получше.
какого-то треша у вас нет.

можно каждую ветку if положить в отдельное свойство computed или просто функцию.
так же можно сделать с повторяющимися filter, но их просто в метод.
Array.prototype.push.apply можно еще на spread заменить.
Ответ написан
Комментировать
@grinat
Для начала убрать весь этот ад в множествеными filter разбив на переменные исходя из названия которых будет ясно что получим в итоге либо разбить на большее количество computed, скорее всего после этого станет очевидно как можно оптимизировать. На данный момент это нечитабельная лапша, которая станет ещё более нечитабельной по мере увеличения числа фильтров
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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