E
E
Eugene Chefranov2019-07-12 19:27:32
JavaScript
Eugene Chefranov, 2019-07-12 19:27:32

How to optimize multiple filter?

There is such an advanced search panel
5d28b33d90543127344302.jpeg
In the computed section, I currently filter the trace. way (not all filters are there yet):

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;
            }
          });
      }
    },
  }

Several filters can be used at the same time. If none of the filters are filled, then displays all the items.
Well, the question is, how can this be reduced / optimized? I thought I could take it to the function and pass parameters, but it seems to me that a lot of code will come out anyway.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
V
Vasily, 2019-07-12
@Chefranov

Separate each filter into a separate computed that returns a function or null.
Another computed array of filters.
And already apply this array of filters.

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;
  } 
}

R
Robur, 2019-07-12
@Robur

You will have as much code as you need to implement the logic, you still won’t be able to reduce it to a couple of lines, you can only reduce / organize it a little better.
you don't have any bug.
you can put each if branch in a separate computed property or just a function.
the same can be done with repeated filters, but they are simply in the method.
Array.prototype.push.apply can also be replaced with spread.

G
grinat, 2019-07-12
@grinat

To begin with, remove all this hell in multiple filters by breaking it into variables based on the names of which it will be clear what we will end up with or split into more computed, most likely after that it will become obvious how to optimize. At the moment this is unreadable noodles, which will become even more unreadable as the number of filters increases

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question