0

I have a function like so:

function contains(needle,haystack) {
    return $.each(haystack,function(i,v) {
        if(v == needle) {
            console.log('true, so return');
            return true;
        }
        if(typeof v == 'object') {
            return app.contains(needle,v);
        }
        console.log('I have not yet returned');
        return false;
    });
}

When I pass something into it (let's say an object of length 2, with one item matching) the console shows:

true, so return
I have not yet returned
I have not yet returned

Why is this? How do I fix it?

Bird87 ZA
  • 2,313
  • 8
  • 36
  • 69

2 Answers2

2

Returning true/undefined from the each callback will continue executing the next iteration.

What you need to do is to use a flag and if a match is found then set the flag to true and return false so that rest of the iterations will be ignored

function contains(needle, haystack) {
    var result = false;
    $.each(haystack, function (i, v) {
        if (v == needle) {
            console.log('true, so return');
            result = true;
            return false;
        }
        if (typeof v == 'object') {
            if (app.contains(needle, v)) {
                result = true;
                return false;
            }
        }
        console.log('I have not yet returned');
    });
    return result;
}
Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
-1

It is because you return only from inner function of each $.each iteration.

To break $.each loop you need return false, so return !result will return false if and only if result if found

function contains(needle,haystack) {
    var result = false;

    $.each(haystack,function(i,v) {
        if(v == needle) {
            result = true;
            return !result;
        }
        if(typeof v == 'object') {
            result = contains(needle,v);
            return !result;
        }
    });

    return result;
}

http://jsfiddle.net/8dggq7ds/2/

Or shorter version

function contains(needle,haystack) {
    var result = false;

    $.each(haystack,function(i,v) {
        return !(result = (typeof v === 'object') ? contains(needle,v) : v == needle);
    });

    return result;
}

Moreover, recursion call app.contains() change to contains().

Arūnas Smaliukas
  • 3,231
  • 6
  • 27
  • 46