i

Strukturierung: Die Listenfunktion map und anonyme Funktionen

Listen verändern mit map

Möchten wir alle Elemente einer Liste verarbeiten, benötigen wir eine Möglichkeit, Funktionen auf jedes einzelne Element einer Liste anzuwenden. Hierfür wird die Funktion map genutzt. Zu beachten ist, dass die Rückgabe des map-Ausdrucks eine neue Liste darstellt. (Stichwort: Unveränderlichkeit). Die übergebene Liste bleibt unverändert.

Mit der Funktion map können wir eine Funktion auf jedes Element einer Liste anwenden. map bekommt eine Funktion und eine Liste übergeben. Die übergebene Funktion wird anschließend auf jedes Listenelement angewandt. Die neu entstandenen Elemente werden zu einer neuen Liste zusammengefügt und zurückgegeben.
Der Aufbau eines korrekten map-Ausdrucks in Racket besteht aus:
  1. Dem Operator map
  2. Einer Funktion als ersten Operanden
  3. Einer Liste als zweiten Operanden.
(map natural? (list 42 17 24 4.1))

(map string-length (list "Informatik" "Racket" "Funktion"))
Bei Ausführung des Ausdrucks wird die übergebene Funktion auf alle Elemente der übergebenen Liste angewandt. Damit dies gelingt, müssen die Signaturen der Funktionen beachtet werden! Die Anzahl und der Datentyp eines Elements in der Liste müssen den erwarteten Übergabedaten der anzuwendenden Funktion entsprechen.

Aufgabe 1: Zulässige Funktionen

(a) Bestimme und begründe, welche der fünf Ausdrücke korrekt sind und welche nicht:

;Ausdruck 1
(map string-length (list 1 4 10 5 6))

;Ausdruck 2
(map string? (list "Hallo" "Welt" "!"))

;Ausdruck 3
(map string? (list 4.5 7 8 #t 18))

;Ausdruck 4
(map ceiling (list (list 1 2 3) (list 3 4 5) (list 6 7 8)))

;Ausdruck 5
(map < 0 (list 17 -15 15 0 -4))

Anonyme Funktionen

Möchten wir Funktionen auf die Elemente der Liste anwenden, die nicht nativ in Racket vorhanden sind, können wir diese wie gewohnt selbst definieren ...

(define verdopple
  (lambda (x)
    (* x 2)
))  
... und anschließend im map-Ausdruck anwenden:
(map verdopple (list 0 1 2 3))
Da man im Zweifelsfall nicht für jede Verarbeitung eine neue Funktion definieren möchte, gibt es die Möglichkeit, die Logik der Funktion innerhalb des map-Ausdrucks zu verfassen.

Anstelle eines Funktionsnamens wird in den map-Ausdruck der gesamte lambda-Ausdruck einer theoretischen Funktionsdefinition geschrieben.

Der Ausdruck ...

(map (lambda (x) (* x 2)) (list 0 1 2 3))
... liefert somit dasselbe Ergebnis wie:
(define verdopple
  (lambda (x)
    (* x 2)
))

(map verdopple (list 0 1 2 3))

Einen lambda-Ausdruck, ohne eine Funktionsdefinition mittels define, nennen wir eine anonyme Funktion.

Eine anonyme Funktion ist eine Funktion, für die kein Name definiert worden ist.
Eine anonyme Funktion ist im Code nicht wiederverwendbar, da sie mit keinem Funktionsnamen aufgerufen werden kann. Bei einmaliger Nutzung oder kurzer Funktionslogik ist eine Funktionsdefinition jedoch nicht zwingend notwendig und es kann den Code übersichtlicher gestalten, anonyme Funktionen zu nutzen. Ob du für deine Programme anonyme Funktionen nutzen willst oder nicht, ist am Ende deine eigene Entscheidung.

Aufgabe 2: Definitionen und anonyme Funktionen

Leere Datei - muss nicht gespeichert werden

(a) Betrachte die folgenden zwei Definitionen...

(define minus-eins-v1
  (lambda (x)
    (- x 1)
))
(define minus-eins-v2
  ((lambda (x)
    (- x 1)) 20)
)
... welche Ausgaben in der REPL erwartest du nach der Ausführung der folgenden beiden Zeilen?
> minus-eins-v1
> minus-eins-v2

(b) Überprüfe deine Vermutung aus (a).

(c) Bei welchem der beiden lambda-Ausdrücke handelt es sich um eine anonyme Funktion?

Aufgabe 3: Nutzung von anonymen Funktionen

Bestehende Datei - listenFunktionen.rkt

(a) Entwerfe einen Racket Ausdruck, der eine Liste zurückgibt, deren Elemente jeweils die doppelte Zeichenanzahl der Elemente folgender Liste enthalten: (list "Informatik" "Racket" "Funktion"). Nutze dazu eine anonyme Funktion.

(b) Für eine Prüfung wurde folgende anonymisierte Notenliste veröffentlicht:
(list 9 4 7 11 9 10 8 10 10 8 3 7 13 7 15 5 3 8 11 6 7)
Schreibe einen Ausdruck, der eine Liste zurückgibt, welche für jeden Notenwert bestimmt, ob dieser als bestanden (#t) oder nicht bestanden (#f) zu werten ist. Nutze dazu eine anonyme Funktion.


Zusatz: map auf mehreren Listen

Bisher haben wir map immer nur auf die Elemente einer Liste angewandt. Wenn die Funktion, die map als ersten Operanden erhält, selbst mehr als einen Operanden besitzt, dann können mit map auch mehrere Listen verarbeitet werden.

Aufgabe 4: map auf mehreren Listen

Bestehende Datei - listenFunktionen.rkt

(a) Welches Ergebnis erwartest du bei folgendem Ausdruck? Überprüfe deine Vermutung.

> (map + (list 0 1 2 3) (list 42 41 40 39))  

(b) Schreibe einen map-Ausdruck, welcher die einzelnen Positionen der folgenden beiden Listen auf Gleichheit prüft.

;Liste 1
(list 234 1233 87523 9653 12345)
;Liste 2
(list 234 1233 87533 9653 13345)

(c) Schreibe einen map-Ausdruck, welcher aus den folgenden drei Listen eine Liste erzeugt, welche pro Position den jeweiligen Maximal-Wert der Listen enthält.

;Liste 1
(list 10 2 3)
;Liste 2
(list 1 20 3)
;Liste 3
(list 1 2 30) 

(d) Im Folgenden findest du fünf Listen, die in fünf Sprachen jeweils die Monatsnamen von Januar bis März beinhalten. Schreibe einen map-Ausdruck, welcher eine Liste-aus-Listen zurückliefert. In den inneren Listen sollen jeweils alle Bezeichnungen für einen Monat zusammen gelistet sein.

;Deutsch
(list "Januar" "Februar" "März")
;Englisch
(list "Januray" "February" "March")
;Spanisch
(list "Enero" "Febrero" "Marzo")
;Türkisch
(list "Ocak" "Şubat" "Mart")
;Kroatisch
(list "Siječanj" "Veljača" "Ožujak")

Suche

v
100.137.3.3.1.2 Strukturierung: Die Listenfunktion map und anonyme Funktionen
Kopieren durch Anklicken

Rückmeldung geben