List Comprehensions – Erlangs elegante for-Schleife


In Erlang gibt es das besondere Konstrukt der List Comprehension um elegant und ohne viel Code eine List von Zahlen schnell erzeugen zu können.

Sie werden meist in den folgenden Fällen eingesetzt:

  1. Anwendung einer Funktion auf eine Liste
  2. Filterung einer Liste
  3. verschachtelte for-Schleifen

Der Syntax der List Comprehensions

[Expression || Generaotor1, Guard11,...GuardN1, Generator2, Guard12,......GeneraotorM, Guard1M,...GuardNM,]

Expression: spezifiziert die Ergebniselement der Ergebnisliste

Generator: vergleichbar mit einer for-Schleife, bei der jedes Element der Liste durchlaufen wird: Syntax: Element<-Liste

Guards: haben eine Filter-Funktion, die bestimmt, ob ein Element in der Ergebnis-Liste landet

Einfache Beispiele für Lists Comprehensions

[X||X<-[1,2,3,4]].        
[1,2,3,4]
[X||X<-[1,2,3,4], X < 3].
[1,2]
[X||X<-[1,2,3,4], X rem 2 == 0].
[2,4]

Nützliche Funktionen bei Verwendung mit Lists Comprehensions

lists:seq() erzeugt ähnlich einer for-Schleife Zahlen in einem Intervall. Der dritte optionale  Parameter ist für den Inkrementwert zuständig.

lists:seq(1,10).
[1,2,3,4,5,6,7,8,9,10]
lists:seq(1,10,2).
[1,3,5,7,9]
lists:seq(10,1,-1).
[10,9,8,7,6,5,4,3,2,1]

lists:sum() summiert alle Elemente einer Liste auf und gibt das Ergebnis zurück.

lists:sum(lists:seq(1,10)).
55

Beispiele für fortgeschrittene Anwendungen der Lists Comprehensions

Problem: Alle Zahlen einer Liste kleiner 10 verdoppeln und aufsummieren.

Lösung:

lists:sum([X*2||X<-lists:seq(1,20), X < 10]).
90

Problem: Aus einer Liste alle Zahlenkombinationen (Paare) generieren der Form [{1,1},{1,2},{1,3} usw., dies entspricht einer doppelten for-Schleife in imperativen Programmierung

[{X,Y}||X<-lists:seq(1,10),Y<-lists:seq(1,10)].
[{1,1},
 {1,2},
 {1,3},
 {1,4},
 {1,5},
 {1,6},
 {1,7},
 {1,8},
 {1,9},
 {1,10},
 {2,1},
  ....

Problem: Aus einer Liste sollen alle Zahlenpaare generiert werden ohne die Paare der Form {1,1},{2,2}

[{X,Y}||X<-lists:seq(1,10),Y<-lists:seq(1,10), X /= Y].        
[{1,2},
 {1,3},
 {1,4},
 {1,5},
 {1,6},
 {1,7},
 {1,8},
 {1,9},
 {1,10},
 {2,1},
 ...

Dies entspricht bspw. in PHP folgendem Code (nur zum Verständnis):

$list = array();
for($i = 1, $1 <= 10, $i++)
{
 for($j = 1, $j <= 10, $j++)
 {
    if($i != $j)
    {
      $list[] = array($i, $j);
    }
  }
}

Weitere kompliziertere Beispiele findet man auf Erlang.org