map / split Konstrukt - wie funktioniert das?

map / split Konstrukt - wie funktioniert das?

am 09.06.2006 10:40:12 von Matthias Tietze

Hallo,

beim Lernen für eine Prüfung bin ich in meinen Unterlagen auf ein Beispiel
gestoßen, das leider von unserer Dozentin nicht weiter erklärt wurde......
Kann mir jemand die Funktionsweise schildern?

@result = map { my @ digits = split //,$_;
If($digits [-1] == 4)
{
@digits;
}
Else
{
();
}
}
@input_numbers;



Gruß und Danke!
Matthias Tietze

Re: map / split Konstrukt - wie funktioniert das?

am 09.06.2006 11:06:34 von Wolf Behrenhoff

Matthias Tietze schrieb:
> Hallo,
>
> beim Lernen für eine Prüfung bin ich in meinen Unterlagen auf ein Beispiel
> gestoßen, das leider von unserer Dozentin nicht weiter erklärt wurde......
> Kann mir jemand die Funktionsweise schildern?
>
> @result = map { my @ digits = split //,$_;
> If($digits [-1] == 4)
> {
> @digits;
> }
> Else
> {
> ();
> }
> }
> @input_numbers;

Wenn man jetzt mal davon absieht, dass es kein If und kein Else gibt und
dass das Leerzeichen zwischen @ und digits überflüssig ist, tut der Code
folgendes:
map { BLOCK } @array führt für jedes Element aus @array den BLOCK aus
und hängt den Rückgabewert an den Block an. In diesem Beispiel werden
alle Elemente aus @input_numbers in ihre einzelnen Buchstaben (bzw.
Ziffern) aufgeteilt und in @digits gespeichert. Dann wird geguckt, ob
das letzte Zeichen eine 4 ist - wenn ja, wird dieses Element aus
@input_numbers - aufgesplittet in einzelne Zeichen - an @result
angehängt. Wenn nicht - dann nicht.

Ich frage mich hier, warum erst der split gemacht wird und dann nach dem
letzten Zeichen geguckt wird - ich hätte es umgekehrt gemacht. Also
.... map { substr($_,-1,1)==4 ? split // : () } ...
das ist nicht nur kürzer, sondern auch wesentlich besser lesbar!

Wolf

Re: map / split Konstrukt - wie funktioniert das?

am 09.06.2006 11:09:25 von Mirco Wahab

Thus spoke Matthias Tietze (on 2006-06-09 10:40):

> beim Lernen für eine Prüfung bin ich in meinen Unterlagen auf ein Beispiel
> gestoßen, das leider von unserer Dozentin nicht weiter erklärt wurde......

LOL, hoffentlich nicht:
"von unserer Dozentin nicht weiter erklärt [werden konte]" ;-)

> Kann mir jemand die Funktionsweise schildern?
> @result = map { my @ digits = split //,$_;
> If($digits [-1] == 4)
> {
> @digits;
> }
> Else
> {
> ();
> }
> }
> @input_numbers;

Das ist die falsch geschriebene Variante
(Else) von:

my @result = map {
my @digits = split //, $_;
$digits[-1] == 4 ? @digits : ();
} @input_numbers;

Hier passiert folgendes:
liste2 <== map {AUSDRUCK } <== liste1;

Pseudocode:

foreach @liste1 {
liste2[$_] = EXPRESSION( liste1[$_] );
}

Konkret:

Für jedes Element der Liste/des Arrays
@input_numbers wird der map{}-Block
aufgerufen. Was passiert im map-Block:

- my @digits = split //, $_;

es wird ein temporäres Array @digits
erzeugt, welches aus den Ziffern der
"Zahl" aus $input_numbers[i] besteht,
z.B. 3442 => (3,4,4,2)

- $digits[-1] == 4 ? @digits : ();

jetzt wird geschaut, ob die letzte Ziffer
davon (digits[-1] oder digits[$#digits])
als "numerische" 4 ausgewertet werden kann.

Wenn ja, wird das Array von Ziffern @digits
von map an das Array @result weitergereicht,
wenn nein, wird nichts (eine leere Liste =>() )
durchgereicht.

Das Ganze wird für jedes Element wiederholt,
@result besteht dann aus einer Liste von Ziffern.

Wer weiss, ob das überhaupt so beabsichtigt war ;-)

Viele Grüße

Mirco

Re: map / split Konstrukt - wie funktioniert das?

am 09.06.2006 11:09:51 von Daniel Fischer

Matthias Tietze!

> beim Lernen für eine Prüfung bin ich in meinen Unterlagen auf ein Beispiel
> gestoßen, das leider von unserer Dozentin nicht weiter erklärt wurde......
> Kann mir jemand die Funktionsweise schildern?

Das Konstrukt 'map { code } liste' wendet einen Code-Block auf alle
Elemente einer Liste an; das Ergebnis ist eine Liste aus den Ergebnissen
dieser Aufrufe. Näheres mit perldoc -f map.


Gruß
Daniel

Re: map / split Konstrukt - wie funktioniert das?

am 09.06.2006 11:22:51 von Matthias Tietze

"Mirco Wahab" schrieb im Newsbeitrag
news:e6be39$857$1@mlucom4.urz.uni-halle.de...
> Thus spoke Matthias Tietze (on 2006-06-09 10:40):
>
>> beim Lernen für eine Prüfung bin ich in meinen Unterlagen auf ein
>> Beispiel
>> gestoßen, das leider von unserer Dozentin nicht weiter erklärt
>> wurde......
>
> LOL, hoffentlich nicht:
> "von unserer Dozentin nicht weiter erklärt [werden konte]" ;-)
>

:-) Auch das würde ich Ihr zutrauen ....

Vielen Dank für eure Antworten!

Gruß
Matthias

Re: map / split Konstrukt - wie funktioniert das?

am 09.06.2006 13:47:20 von Daniel Fischer

Matthias Tietze!

>> LOL, hoffentlich nicht:
>> "von unserer Dozentin nicht weiter erklärt [werden konte]" ;-)
>
> :-) Auch das würde ich Ihr zutrauen ....

Das mit der Großschreibung würde ich nicht zu hoch bewerten. Mit kleinem
if und else funktioniert es ja, auch wenn es umständlich ist. Letzteres
ist aber typisch für Lehrer, die nicht immer die neuen Konstrukte
erklären wollen. Bedingungen und split kennt man in einem perl-Kurs
wahrscheinlich von Anfang an. Die Großschreibung kann dagegen einfach ein
Word-Unfall sein. Viele Textverarbeitungen verhunzen Code durch
automatische Großschreibung am Zeilenanfang, und das sind auch
tatsächlich die einzigen beiden Stellen, wo fälschlicherweise
Großbuchstaben stehen.


Gruß
Daniel

Re: map / split Konstrukt - wie funktioniert das?

am 09.06.2006 16:14:19 von Ferry Bolhar

Mirco Wahab:

> - $digits[-1] == 4 ? @digits : ();
>
> jetzt wird geschaut, ob die letzte Ziffer
> davon (digits[-1] oder digits[$#digits])
> als "numerische" 4 ausgewertet werden kann.

Nein, es wird ganz einfach mit der Zahl 4 verglichen
und das Programm mit einem Laufzeitfehler

"Argument <...> isn't numeric..."

abgebrochen, falls ein solcher Vergleich nicht möglich
ist, dh., eines der Elemente in @input_numbers keine
Zahl enthält. Der Inhalt von @input_numbers sollte vor
der Ausführung dieses Codes entsprechend geprüft
werden, um obige "Abstürze" zu vermeiden, oder man
verwendet gleich eine Rexeg:

if ($digits[-1} =~ /^4$/) ...

Übrigens vermute ich, dass das Beispiel ganz bewusst
komplizierter als notwendig gehalten ist, schließlich
handelt es sich um eine Übung, wo man ja eben erst
draufkommen soll, was eigentlich passiert.

LG, Ferry

--
Ing. Ferry Bolhar
Municipality of Vienna, Department 14
A-1010 Vienna / AUSTRIA
E-mail: bol@adv.magwien.gv.at