Logo

Programming-Idioms

  • PHP
  • Go
  • JS
  • Java

Idiom #223 for else loop

Loop through list items checking a condition. Do something else if no matches are found.

A typical use case is looping through a series of containers looking for one that matches a condition. If found, an item is inserted; otherwise, a new container is created.

These are mostly used as an inner nested loop, and in a location where refactoring inner logic into a separate function reduces clarity.

Predicate<Item> condition;
items.stream()
	.filter(condition)
	.findFirst()
	.ifPresentOrElse(
		item -> doSomething(i),
		() -> doSomethingElse());

This requires at least Java 8, and uses a stream instead of a loop to get to the same result.
import static java.lang.System.out;
 a: {
     b: {
            int i, n = items.size();
            for (i = 0; i < n; ++i)
                if (f(items.get(i)))
                    break b;
            out.println("not found");
            break a;
        }
        out.println("found");
    }
boolean b = false;
for (int i = 0; i<items.length; i++) {
	if (items[i] == something) {
		doSomething();
		b = true;
	}
}
if (!b)
	doSomethingElse();

Java does not have a for else loop natively. Therefore we must use a boolean value to do something if no matches are found.
function search(array $haystack, string $needle, callable $doSuccess, callable $doFail)
{
    foreach ($haystack as $item) {
        if ($item === $needle) {
            $doSuccess();
            return;
        }
    }
    $doFail();
}

$items = ["foo", "bar", "baz", "qux"];
search(
    $items,
    "baz",
    static function () {
        echo "found it";
    },
    static function () {
        echo "not found";
    }
);
for _, item := range items {
    if item == "baz" {
        fmt.Println("found it")
        goto exit
    }
}
{
    fmt.Println("not found")
}
exit:

Go does not have a for...else construct, but a structured goto label works well.
const found = items.some(condition);

if (!found) doSomethingElse();
(if (seq (filter odd? my-col))
  "contains odds"
  "no odds found")

(seq (filter pred-fn col)) returns nil when there are no matches, and nil is falsy.

New implementation...
< >
Ruien