58

Is there a Javascript equivalent of the python 'for-else' loop, so something like this:

searched = input("Input: ");
for i in range(5):
    if i==searched:
        print("Search key found: ",i)
        break
else:
    print("Search key not found")

Or do I just have to resort to a flag variable, so something like this:

var search = function(num){
    found = false;
    for(var i in [0,1,2,3,4]){
        if(i===num){
            console.log("Match found: "+ i);
            found = true;
        }
    }
    if(!found){
        console.log("No match found!");
    }
};
SimonT
  • 2,219
  • 1
  • 18
  • 32
  • 2
    You need the flag value. Or, in your case, just return after you found a match. – Guntram Blohm Feb 03 '14 at 10:50
  • 2
    You'll have to use the boolean. There's no `for-else` – Cerbrus Feb 03 '14 at 10:50
  • Bummer...oh well. Some of the syntax was surprisingly similar to the "simplicity" of python, so I figured it would be worth asking. –  Feb 03 '14 at 10:51
  • Yes you will have to implement one with your own code .. there is no for else loop in javascript – A J Feb 03 '14 at 10:51
  • 1
    Note: `var i in [0,1,2,3,4]` --> i actually contains the index, rather than the value. They are the same in this case, but not in general. – nhahtdh Feb 03 '14 at 10:52

8 Answers8

32

Yes, it is possible to do this without a flag variable. You can emulate for … else statements using a label and a block:

function search(num) {
    find: {
        for (var i of [0,1,2,3,4]) {
            if (i===num) {
               console.log("Match found: "+ i);
               break find;
            }
        } // else part after the loop:
        console.log("No match found!");
    }
    // after loop and else
}

That said, I would recommend against doing this. It is a very unconvential way of writing this and will lead to poor understanding or confusion. An early return is acceptable though, and can be used in a helper function if you need to continue with execution after the loop.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
17

Working example (you need to use the flag):

var search = function(num){
    var found = false;
    for(var i=0; i<5; i++){
        if(i===num){
            console.log("Match found: "+ i);
            found = true;
            break;
        }
    }
    if(!found){
        console.log("No match found!");
    }
};
Goran.it
  • 5,991
  • 2
  • 23
  • 25
  • 1
    In this example, instead of the `for` loop, you might as well check `num < 5`. – Cerbrus Feb 03 '14 at 10:59
  • @Cerbrus, you are right that should further optimize the function but then we actually don't know what is intended use here .. it might be some search in arrays etc. Anyway nice tip.. – Goran.it Feb 03 '14 at 11:00
  • Except that this function doesn't search any arrays. The array the OP provided was just some sample data. Don't assume the contents are always the same. If you want to search an array like this: `[1,6,3,8,2]`, your code will not work. – Cerbrus Feb 03 '14 at 11:03
  • Exactly, but it's easy to change that for(var i..) to for( var i in) .. without going into details. – Goran.it Feb 03 '14 at 11:04
  • **OP: This function is BAD code.** It's a very inefficient way of checking `num < 5` Why did you accept this answer? Goran: `for(var i in)` will not work for non-ordered arrays. – Cerbrus Feb 03 '14 at 11:05
  • Oh please, how could this be a bad code .. try to do some jsPref on this vs other answers and look which is the fastest. There is nothing wrong in this method – Goran.it Feb 03 '14 at 11:09
  • 1
    You can replace the `for` iterations with a simple `if`. Yes, the output is what you want, but the way you get this output is BAD. Yes, it works with the provided example array, but ONLY because that array is counting up from `0-5` like your `for` does. If **anything** about that array changes, your code won't work. – Cerbrus Feb 03 '14 at 11:10
3

You could use Array.some(), with a testing callback:

if(!items.some( item => testCondition(item) )){
    // else statement
}

Array.some() returns true if any of the elements (or tests) is true, false othewise. You can take advantage of:

  • before returning a truthy value, your testCondition(item) can do whatever you want.
  • Array.some() will stop iterating at the first truthful iteration.

Here's an example:

const findBigItem = (items) => {
    if(!
        // for item in items:
        items.some( item => {
            // here the code for your iteration

            // check for the break condition
            if ( item > 15) {
                console.log("I broke something here: ",item);
                return true; // instead of break
            }
            // by default return null (which is falsy)
        })
    ) { // if no item returned true
        // here goes the else statement
        console.log("I found nothing!");
    }
};

findBigItem([0,1,2,3,4]); //I found nothing!
findBigItem([0,10,20,30,40]); //I broke something here: 20

So Array.some() will iterate over the elements and if any returns true, the loop breaks (it won't go through the rest of the elements). At the end, the value returned by Array.some() will act as a flag: if false you run your else statement.

So the for else logic becomes if not some.

valcapp
  • 293
  • 3
  • 8
2

There is no built-in JavaScript equivalant.

You can emulate this by using return as a control flow. You can put your for loop in an IIFE and use the return to move beyond conditions afterwards. This does mean that vars don't pollute the scope above with variables.

(function() {  // Or `(() => {` in ES6  // Python equivalent:
  for (/* for loop body*/) {            // for <loop body>:
    if (/* Condition */) {              //     if <Condition>:
      // Met condition                  //         <Met condition>
      return;  // Goes past the else    //         break
    }                                   // 
  }//else {                             // else:
    // Never met the condition          //     <Never met condition>
//}
})();

This has the advantage of not using a flag. It is now inside another function, however, so you cannot declare variables to be used outside. You can still get and set variables in the scope above, so you just have to have the var statements outside of the function.

A working example for what you wanted to do:

(function(arr, value) {
  for (var i = 0, length = arr.length; i < length; i++) {
    if (arr[i] === value) {
      console.log("Match found: " + arr[i]);
      return;
    }
  }//else {
    console.log("No match found!");
//}
})([0, 1, 2, 3, 4], +prompt("Input: "));

If you are doing this often, you can create a function to do most of it for you.

function search(arr, condition, forBody, elseBody) {
  for (var i = 0, length = arr.length; i < length; i++) {
    if (condition(arr[i], arr)) {  // if
      return forBody(arr[i], arr);  // then
    }
  }
  return elseBody(arr);  // else
}

var value = +prompt("Input: ");
search([0, 1, 2, 3, 4],
  i => /* if */ i === value,
  i => /* then */ console.log("Match found: " + i),
  () => /* else */ console.log("No match found!"));
Community
  • 1
  • 1
Artyer
  • 31,034
  • 3
  • 47
  • 75
0

You'll have to use the boolean. There's no for-else in JavaScript.

A nice and short way to search would be to use Array.prototype.indexOf():

var search = function(num, arr){
    var index = arr.indexOf(num);
    if(index !== -1)
        return "Match found: " + index;
    }
    return "No match found!";
};

Call it like this, for example:

console.log(search(4, [0,1,2,3,4]));
Cerbrus
  • 70,800
  • 18
  • 132
  • 147
0

In these cases you can do a straight check for the value

if (!(searched in range(5))) { 
    console.log("No match found!"); 
}else{
    console.log(searched + " was found!");
}
Emilio Rodriguez
  • 5,709
  • 4
  • 27
  • 32
-1

You can either use a boolean or you can simply return. Some thing along this line should work...

    var search = function(num){
    found = false;
    for(var i in [0,1,2,3,4]){
        if(i===num){
            console.log("Match found: "+ i);
            return true;
        }
    }
    return false;
};
iJade
  • 23,144
  • 56
  • 154
  • 243
  • Don't assume the OP *always* wants a array like that. If you want to search an array like this: `[1,6,3,8,2]`, your code will not work. – Cerbrus Feb 03 '14 at 11:01
  • @Cerbrus i didn't assume....i wrote as per OPs code.....OP uses the same code in question..... – iJade Feb 03 '14 at 11:04
  • The OP often makes mistakes on StackOverflow. – Cerbrus Feb 03 '14 at 11:06
  • @Cerbrus come on man .....may be he uses only ordered array....You are assuming too much......you should let it go...:) – iJade Feb 03 '14 at 11:08
  • 2
    Ever heard of [Defensive Programming](http://en.wikipedia.org/wiki/Defensive_programming)? Never assume input is formatted the way it has to be. In situations where a function like this would be of use, the array's content are usually dynamic, or at least unknown. – Cerbrus Feb 03 '14 at 11:19
  • @Cerbrus Well at some point you have to assume valid input, right? – David Callanan Feb 07 '20 at 19:11
-1

If your ultimate is goal is to check whether given input is there are not in an array, you can simply make use of indexOf function.

var arr = [1,2,3,4,5]
var lookingFor = 5 ; 

if ( arr.indexOf(lookingFor) > -1 ) {
  console.log("Input is here") ;
} else {
  console.log("Nope");
}

https://jsfiddle.net/7wnasv5e/

Raja G
  • 5,973
  • 14
  • 49
  • 82