map
Beschreibung
map{}() ist eine spezielle Funktion unter Perl, die auf Arrays angewendet wird. Als Ergebnis liefert map wieder ein Array. Mit map wird ein Array durchlaufen und Kopien dieser Werte bearbeitet. Das Array, das map bearbeitet, steht in den runden Klammern (@array). Wie map das betrachtete Array bearbeitet, steht in den geschweiften Klammern {}. Dazu benötigen wir jedoch wieder die Spezialvariable $_, die das aktuell betrachteten Arrayelement enthält. Einige Beispiele:
Beispiele
# Quadrieren von Zahlen
@zahlen=(1..10);
@quadratzahlen=map{$_**2}(@zahlen);
print join(" - ", @quadratzahlen);
1 - 4 - 9 - 16 - 25 - 36 - 49 - 64 - 81 - 100
Das fällt auf:
- In den geschweiften Klammern wird das aktuelle Element quadriert und an das Ergebnisarray weitergegeben.
- Mit join werden die einzelnen Elemente zusammengefügt; die Trennzeichen zwischen den Elementen sind: " - ".
Kürzer geht das natürlich auch:
print join(" - ", map {$_**2}(1..10));
1 - 4 - 9 - 16 - 25 - 36 - 49 - 64 - 81 - 100
- Dem map Befehl braucht nicht unbedingt eine Arrayvariable übergeben werden - es reicht ein Array an sich.
- Das Ergebnis kann außerdem sofort weiterbehandelt werden - wie es eben in Perl üblich ist.
- Das Gleiche gilt für den join-Befehl
# Umrechnung von DM in Euro
@dm_preise=(0.99, 1.39, 2.99, 4.19);
$euro=1.95583;
print join(" DM, ", @dm_preise)."DM\n".
join(", ", map{($_/$euro)." EUR"} @dm_preise);
0.99 DM, 1.39 DM, 2.99 DM, 4.19 DM
0.506178962384256 EUR, 0.710695714862744 EUR, 1.52876272477669 EUR, 2.14231298221216 EUR
- Hier wird in der geschweiften Klammer zuerst der aktuelle Wert durch 1.95583 geteilt und anschließend wird der String "EUR" angefügt. Erst dann wird dieser an join weitergegeben.
- Auf die runden Klammern bei der map-Funktion kann verzichtet werden.
Einige typische Anwendung, bei der sich die map-Funktion bewährt sind ...
Sortieren von Hashes nach den Werten
Der folgende Hash %zugriffe, der die Zugriffe auf HTML-Seiten enthält, soll nach Anzahl der Zugriffe sortiert werden. Um das folgende Beispiel richtig zu verstehen, muss man unbedingt das Kapitel über die Referenzen verstanden haben. Man muss die letzte Zeile des Programms öfter durchlesen (von rechts nach links), um sie zu verstehen.
%zugriffe=(
"start.htm" => 53,
"inhalt.htm" => 123,
"uebungen.htm" => 77,
"einleitung.htm" => 12
);
print join "\n", map{($_->[0]).": ".($_->[1])} sort{$a->[1] <=> $b->[1]} map{[$_, $zugriffe{$_}] } keys %zugriffe;
Der Plan zu diesem Progrämmchen ist folgender:
- Gebe die Schlüsselwerte des Hashes als Array an: keys %zugriffe. Über die Elemente dieses Arrays erreicht man alle Werte des Hashes.
- Mit map erzeugt man ein Array, dessen Elemente anonyme Arrays sind. Ein solches anonyme Array enthält als Elemente den aktuellen Schlüssel $_ und als zweites Element die Anzahl der Zugriffe $zugriffe{$_}.
- Damit haben wir Folgendes erstellt:(["start.htm",53], ["inhalt.htm",123], ["uebungen.htm",77], ["einleitung.htm",12]) - eben ein Array bestehend aus anonymen Arrays als Elemente.
- Dieses Array soll jetzt sortiert werden mit sort und zwar nach der Anzahl der Zugriffe. sort bekommt ja ein Array, von dem jedes Elemente aus einem anonymen Array besteht. Die Anzahl der Zugriffe findet man im zweiten Element dieses anonymen Arrays; d. h., man muss nach dem zweiten Element des anonymen Arrays sortieren. Deshalb ergibt sich folgender Sortierausdruck: $a->[1] <=> $b->[1].
- Damit hat man jetzt das Array bestehend aus den anonymen Array sortiert nach der Anzahl der Zugriffe.
- Jetzt soll das sortierte Array ausgegeben werden auf die Standardausgabe in der Form: Seite: Anzahl. Dazu wandlet man die Elemente des sortierten Arrays (das sind ja die anonymen Arrays, bestehend aus key und value des Ursprungshashes) um in einen String. Natürlich funktioiniert das wieder mit der map-Funktion. Wir nehmen einfach das aktuelle Element $_ - das ja ein anonymes Array ist - und verknüpfen das erste mit dem zweiten Element auf folgende Art und Weise: ($_->[0]).": ".($_->[1]).
- Damit haben wir ein Array bestehend aus Strings der Art Seite: Anzahl.
- Als letztes verknüpfen wir die einzelnen Strings mit Hilfe von join und geben das Ergebnis an print weiter.
einleitung.htm: 12
start.htm: 53
uebungen.htm: 77
inhalt.htm: 123