0

Why doesn't this test pass?

it('lodash_test', function() {
    var arr = [{a: "x", b: [{x: "1", y: "2"}]}, {a: "x", b: [{x: "1", y: "2"}]}, {a: "x", b: [{x: "33", y: "2"}]}]
    var result = _.filter(arr, function(obj) {
        obj.b.forEach(function(item_b) {
            if(item_b.x=="1") {
                return true;
            }
        });
    });
    expect(result).to.be.eql([{a: "x", b: [{x: "1", y: "2"}]}, {a: "x", b: [{x: "1", y: "2"}]}]);
});

1 Answer 1

1

Because forEach's return value is completely ignored, and your _.filter predicate function never returns anything.

You probably wanted to use some:

it('lodash_test', function() {
    var arr = [{a: "x", b: [{x: "1", y: "2"}]}, {a: "x", b: [{x: "1", y: "2"}]}, {a: "x", b: [{x: "33", y: "2"}]}]
    var result = _.filter(arr, function(obj) {
        return obj.b.some(function(item_b) {
    //  ^^^^^^^      ^^^^
            if(item_b.x=="1") {
                return true;
            }
        });
    });
    expect(result).to.be.eql([{a: "x", b: [{x: "1", y: "2"}]}, {a: "x", b: [{x: "1", y: "2"}]}]);
});

Array#some calls the predicate for each entry in the array, stopping the first time the predicate returns a truthy value; its return value is true if the predicate ever returned a truthy value, or false if not.

So the return I've underscored in the above is the return from the _.filter predicate; your original return true is the return from some (formerly forEach).

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

3 Comments

You're a genius :) Thank you! By the way, do you think that it is a performant way to do the job? Are there any better alternatives?
@scaryguy: I think for a small data set, it doesn't matter. It's simple and gets the job done. Worry about performance if and when performance is an issue. :-) Having said that, based on the structure of the data, I'm not immediately seeing how you could do it other than what you're doing; you have to loop through the inner arrays to know if they have x == "1". The JavaScript engine's going to optimize those predicate calls (and even if it didn't, they don't cost anything worth worrying about).
I'm going to use this for an ad server. Instead of doing the same thing in MongoDB, I'm fetching a base number of records and I'm iterating over them to filter odd ones. Maybe it's a very broad question for a "comment" but do you think so this should be more performant than a "db query"? If you'd like to answer, I can add another question for this :)

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.