Logo

Programming-Idioms

  • Lisp
  • Go
  • JS
  • Pascal
  • D
  • C++

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.

#include <algorithm>
if (std::any_of(items.begin(), items.end(), condition))
    baz();
else
    DoSomethingElse();

Calls condition(x) on each element in items until one returns true
#include <list>
bool found = false;
for (const auto item : items) {
  if (item == "baz") {
    baz();
    found = true;
    break;
  }
}
if (!found) {
  DoSomethingElse();
}

c++ 11 implementation

c++ doesn't have for..else construction, so found variable can be used instead
(loop for item in items
      when (check-match item) return (do-something item)
      finally (return (do-something-else))

check-match do-something and do-something-else are all invented function names.

The finally clause runs only if the return clause does not run.
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();
Found := False;
for Item in Items do
begin
  if Item.MatchesCondition then
  begin
    Found := True;
    Break;
  end;
end;
if not Found then 
  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...