0

I have the following construct:

Note: the arrays and the goal in this example are only symbolic! I know that there would be way better solutions for this example - it's just to demonstrate the construct of the code.

var firstArray = [1,2,3,4,5];
var secondArray = [1,2,4,5];

$.each(firstArray,function(i,firstArrayElement){
    $.each(secondArray,function(i,secondArrayElement){
        if(firstArrayElement === secondArrayElement) {
            // do stuff

            // PROBLEM: force the firstArray loop to continue with the next iteration
        }
    });
    console.log("Didn't find: "+firstArrayElement);
});

jsFiddle

To clarify my question: Is there a way to force the parent .each to continue (= skip the console.log) with the next iteration? In PHP this would be continue 2;. So the goal is, to never reach the console.log() if a condition is true (in this example an element is found).

There is the flag solution (jsFiddle), but there has to be a nicer way to do this.

There are also solutions with labels but labels won't work with .each().

So what I am looking for is probably a way to use return in the parent function without flags. For the example above, this would mean that the result logs: Didn't find 3

Community
  • 1
  • 1
Marc
  • 3,683
  • 8
  • 34
  • 48
  • Why don't you reverse both `each` loops. I mean apply `each` on `secondArrayElement` first and thne inside it apply `each` on `firstArrayElement`. This way you can return `false` from within second `each` callback to skip over `firstArrayElement` loop. – Shoaib Shakeel Apr 17 '15 at 12:27
  • @ShoaibShakeel: The problem is, that this won't work because I need to skip code _after_ a loop was completed and there was no condition true (while this code is part of a parent loop's iteration). – Marc Apr 17 '15 at 12:45
  • I don't think any of the suggestions are any "neater" than using a flag or lookup table of sorts. I understand this is symbolic - but I would probably look at using an array diff function and then decide my actions based upon the results. – Andrew Spode Apr 22 '15 at 14:51

4 Answers4

2

So, this is a little hacky...but it does accomplish the goal of returning true to the parent function without flags:

var firstArray = [1,2,3,4,5];
var secondArray = [1,2,4,5];

$.each(firstArray, function(i, firstArrayElement) {
    try
    {
        $.each(secondArray, function(i, secondArrayElement) {
            if (firstArrayElement === secondArrayElement) {
                throw 'Found';
            }
        });
    } catch(err) {
        return true;    
    }

    console.log("Didn't find: "+firstArrayElement);
});
Denis Ali
  • 1,062
  • 7
  • 8
2

The response of $.each method is always the object that was iterated. If we could control this, there would be an option. As we cannot, you won't be able to escape the flag solution.

If you're open to drop $.each, at least in the inner loop, and use for, this should do the job:

var firstArray = [1, 2, 3, 4, 5],
    secondArray = [1, 2, 4, 5];

$.each(firstArray,function(i, firstArrayElement) {
    var x = null;

    for (var j = 0; j < secondArray.length; j++) {
        var secondArrayElement = secondArray[j];

        if (firstArrayElement === secondArrayElement) {
            console.log('Do stuff');
            // return false here if you wan't to break after the first match.

        } else if (j + 1 == secondArray.length) {
            return false;
        }
    }

    console.log('Didn\'t find: ' + firstArrayElement);
});
  • This works for me, because I can use `return true` to skip the iteration of the parent .each just as requested - Thanks – Marc Apr 23 '15 at 06:05
0

EDIT(like somebody else already suggested):

$.each(firstArray,function(i,firstArrayElement){
         var idx = $.inArray(firstArray[i], secondArray);
            if(idx == -1) {
              console.log("Didn't find: "+firstArrayElement);   
            }
            else{
             //to do...
            }
        });

I do not know if it fits your problem...

user4341206
  • 647
  • 1
  • 7
  • 26
  • Tried this before. It will only break the secondArray loop (because it will only return this function). What I need, is to return **true** on the firstArray loop, so it continues with the next iteration. – Marc Apr 13 '15 at 07:39
  • Ok, isn't that you want to achieve ("Is there a way to force the parent .each to continue with the next iteration")? By this you force that parent continues to next iteration (when element is found it goes to next iteration)... – user4341206 Apr 13 '15 at 07:40
  • No it isn't. Your answer does not force the parent .each to continue - it just breaks out of the current .each but will execute the remaining code in the parent iteration. (it "continues" but not in the definition "continue" has in programming languages) – Marc Apr 13 '15 at 07:44
  • As mentioned in the note: it's only symbolic. I need to break out of the .each and not to find stuff in the array. I just made the example up. – Marc Apr 13 '15 at 08:18
0

Solution:

Explanation found in comments.

$.each(firstArray,function(i,firstArrayElement){
    //Initialize skipParent at each Iteration
    var skipParent = false;
    $.each(secondArray,function(i,secondArrayElement){
        if(firstArrayElement === secondArrayElement) {
            // do stuff
            //set skipParent to true
            skipParent = true;
        }
    });
    //if skipParent true, we continue to next iteration.
    if(skipParent)
    {
        console.log("Didn't find: "+firstArrayElement);
        return false;
    }

});
Mysteryos
  • 5,581
  • 2
  • 32
  • 52
  • Well thats the flag solution I mentioned in the question... Would like to avoid this - as it's possible in PHP – Marc Apr 13 '15 at 08:09