3

I have an array that contain filter functions that need to be applied to an array of items in Lazy.js. I've tried using a for-loop but only the last filter is applied.

function (searchText) {
    var result = Lazy(input);

    for (var query of this.querylist) {
        result = result.filter((item) => {
            return query.filterFunc(item, searchText, query.compareFunc);
        });
    }

    return result.toArray();
}

Is there a way of applying a list of filters without hardcoding the chaining?

Here is a fiddle showing the issue

A. Li
  • 33
  • 8

1 Answers1

5

You can use reduce to iterate over the filters and create a resulting one by applying each one to the previous one.

var result = Lazy(contentArray);

var allFilters = filters.reduce(function(acc, current) {
    return acc.filter((item) => current.filterFunc(item)); // return the last one with the current filter applied
}, result); // start with the original one


console.log(allFilters.toArray())

You can find an updated fiddle here.

The reduce is just a nicer and more generic way of this:

var allFilters = result
                  .filter(filters[0])
                  .filter(filters[1])
                  .filter(filters[2]);

Lazy.js will not call the filters until you call toArray or forEach. I put some logs in this example.

toskv
  • 30,680
  • 7
  • 72
  • 74
  • does reduce() resolve partly, or is query resolution deferred until allFilters.toArray() is called. Does it still have significant performance gains compared to lodash or underscore? – A. Li Feb 29 '16 at 16:53
  • 1
    all reduce does is to create a Lazy array that has all the filters in the filters array applied to it. The actual invocation is done when toArray is called. Regarding performance gain.. I have no idea. I never actually tested the performance of those libraries. – toskv Feb 29 '16 at 20:15