skip to Main Content

If ‘break’ is called inside a recursive function will it break all the iterations of it being called or will it just cancel that instance? Specifically I want to know about the following code:

//take a 2d array and check if it is in _switch
function checkSwitch(arr2d, rates, n = 0, found = []){
    if(n===arr2d.length){
        inCase(found, rates)
        break
    }
    for(let i in arr2d[n]){
        if(deepCheck(_switch, [...found, arr2d[n][i]]))
        checkSwitch(arr2d, rates, n+1, [...found, arr2d[n][i]])
    }
    return false
}

I have a 2d array (array of arrays) and I check if one element from each of the arrays is included as nested object keys in this _switch I am making. When I have an all match then run a function, and I want to continue checking the 2d array to see if there are other matches.

However, if I ever come across an array with no matches in it then I need to break all iterations of the recursion for efficiency because I know there cannot logically be any matches of one from each.

So I need to be able to break one instance and to break all of them. I am not sure how to obtain this.

CORRECTED CODE AND LESSONS LEARNED
I am amazed at how much I am learning about what intellignece actually is while working on artificial intelligence. In a recursive function adding in a return value will break the current instance and if you check the return when calling the recursion then you can passback the collapse of the entire recursion. Here is the new code:

function checkSwitch(arr2d, rates, n = 0, found = []) {
    if (n === arr2d.length) {
        inCase(found, rates);
        return true;
    }
    let tf = false
    for (let i in arr2d[n]) {
        if (deepCheck(_switch, [...found, arr2d[n][i]])) {
            if (!checkSwitch(arr2d, rates, n + 1, [...found, arr2d[n][i]])) {
                return false;
            } else {
                tf = true
            }
        }
    }
    return tf;
}

Returning true means break this iteration and keep going, while returning false means break everything. I added in a toggle right before the for loop so that if we happen to get a match of one from every array, then logically we need to check every other possibility because they may be valid. otherwise if we get through the for without getting a true then break everything because there are no longer any possibilities.

3

Answers


  1. Neither. Loop control statements like break and continue are only valid inside a loop (for, while, do, or switch). The break statement in your code is not in a loop, so this code will cause a syntax error.

    The only way to “break out” of multiple levels of a recursive function is to throw an exception. This is probably not ideal for this situation; a better option for your situation may be to use a nested loop instead of recursion.

    Login or Signup to reply.
  2. A break statement will terminate only the current loop, switch or label statement. It is the wrong tool to use for what you are trying to accomplish. (It should not be used at all where you have it, since it is outside one of those constructs.) A better approach is to have checkSwitch return a value indicating whether the matching process should be abandoned. That value can then percolate back up the recursion stack. Alternatively, throw an exception (which you will then have to catch somewhere).

    Login or Signup to reply.
  3. You could simply use return instead, and always check the result from the caller’s perspective. In this case you’ll need to return a different value when it “breaks”:

    function checkSwitch(arr2d, rates, n = 0, found = []) {
      if (n === arr2d.length) {
        inCase(found, rates);
        return true;
      }
      for (let i in arr2d[n]) {
        if (deepCheck(_switch, [...found, arr2d[n][i]])) {
          if (checkSwitch(arr2d, rates, n + 1, [...found, arr2d[n][i]])) {
            return true;
          }
        }
      }
      return false;
    }
    

    Here, returning true basically means “stop everything” (break out), and returning false means stop the current iteration normally (as OP explained himself in the comments below).

    This does not technically “break out”, but will instead roll back up the call chain before returning, which is (imho) the cleanest approach (though technically not as optimal as breaking in one go) if you’re going to stick to a recursive function.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search