1

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.

5
  • do you need to return the filtered list? or just iterate to run the .show() method? Commented Dec 27, 2016 at 22:23
  • just iterate to run the show() method Commented Dec 27, 2016 at 22:24
  • @hackerrdave just iterate to run the show() method Commented Dec 27, 2016 at 22:26
  • no need/point to use filter if not returning anything - for loop or Array.prototype.forEach() will do the trick Commented Dec 27, 2016 at 22:29
  • Why down voting guys? Commented Dec 27, 2016 at 22:36

2 Answers 2

3

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).

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for the answer .I know about the forEach but I want to use filter().Is that possible?
I mean no disrespect, it's possible, but it's a bit dumb. I'll add more to my answer.
Why is it dumb?
I added some explanation in the answer. Does that help?
Thanks for the explanation
|
3

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>

2 Comments

This is what I originally had tried but for some reason it is not working
If your list has numeric values, make sure to convert the attribute value to numeric also, with the unitary +. See modified answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.