Manos Kounelakis
Manos Kounelakis

Reputation: 3181

rewrite for loop as filter() javascript

I have the following JavaScript code:

var selectEnabledGenerators = function(generators) {
    //List of generator indexes to show
    var list = generators;
    var allGenerators = $(".generatorContainer");
    //Hide all generators
    allGenerators.hide();
    //maybe use filter here?
    for (var i = 0, max = list.length; i < max; i++) {
        $(".generatorContainer[data-generator=" + list[i] + "]").show();
    }
};

Is there any way to rewrite the for loop using filter()? I know that I can use a for each loop but I want to do this by using filter.

Upvotes: 1

Views: 143

Answers (2)

trincot
trincot

Reputation: 350841

You could use .filter() like this:

allGenerators.filter(function () {
    return list.indexOf(+$(this).attr('data-generator')) > -1
}).show();

Simplified demo:

$('div').hide().filter(function (i) {
  return [1,3].indexOf(+$(this).attr('data-generator')) > -1
}).show();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-generator=1>test1</div>
<div data-generator=2>test2</div>
<div data-generator=3>test3</div>
<div data-generator=4>test4</div>

Upvotes: 3

Paarth
Paarth

Reputation: 10397

There's no need to use filter here. Since you're not returning anything forEach would be the more appropriate function.

Something along the lines of this should do:

list.forEach(item => $(".generatorContainer[data-generator=" + item + "]").show());

or

list.forEach(function(item){
    $(".generatorContainer[data-generator=" + item + "]").show();
});

if you don't like/can't use lambdas


Can I use filter anyway

Yes. But there's really no reason to. If I saw you using filter in this way I would reject your code review.

The use case of filter is to quickly pare down a list of items by passing in a predicate function (a function that answers "does this stay in"). This function's type for an Array<T> would be T => boolean. This filter function will execute the predicate function's code block on every item and then check the return value of that predicate function. If that return value is truthy, it will mark that object that was passed into the predicate function and then return all the objects that resulted in truthy values as a new array. forEach will also execute a function on each parameter, just without doing the extra work of returning a value and managing a new list.

If you do not make use of the returned result from filter, it is nonsensical to use filter. Not only is it useless, it will confuse people reading your code in the future who are trying to understand why you use filter here.

Ultimately the code is the same:

list.filter(item => $(".generatorContainer[data-generator=" + item + "]").show());

The .show() is treated as a side effect (which filter functions really should not have).

Upvotes: 3

Related Questions