Ich möchte eine Datenstruktur bestehend aus Strings, Arrays und
Arrayreferenzen durchlaufen und Werte darin ändern. Also aus
$VAR1 = [
'eins',
'zwei',
'zweieinhalb',
[
'drei',
'vier',
[
'fünf',
'sechs'
]
]
];
soll dann etwa
$VAR1 = [
'EINS',
'ZWEI',
'ZWEIEINHALB',
[
'DREI',
'VIER',
[
'FüNF',
'SECHS'
]
]
];
werden, wenn das Ziel ist, alle Strings in Großbuchstaben zu wandeln.
Ich mache das bisher mit folgendem rekursiven Code (lauffähig unter
http://paste.debian.net/51506/ verfügbar):
my @a = ('eins', 'zwei', 'zweieinhalb',
['drei', 'vier',
['fünf', 'sechs']
]
);
@a = upupup(@a);
sub upupup {
return map {upupup($_)} @_ if scalar(@_) > 1;
return [map {upupup($_)} @{$_[0]}] if (scalar(@_)==1 and ref($_[0]) eq 'ARRAY');
return map {uc($_)} @_;
}
Der Code erfüllt die Aufgabenstellung, ist aber nicht schön. Dazu
einige Fragen:
1. Ich kann das doch nicht alles mit einem einzigen map abfrühstücken,
richtig? D.h. ich muss die Datenstruktur von Hand durchlaufen und
wieder eins zu eins zusammensetzen, ja? Mit anderen Worten, Perls
map verhält sich so, wie man's von map[0] erwartet?
2. Das if-Statement und das hin-und-hercasten im Rumpf des zweiten
Falles ist selten dämlich. Geht das schöner?
3. Gibt es ein Modul welches diese Funktionalität (also eine Art
"Tiefenmap", also ein etwas abgespecktes foldr[1]) schon bietet?
Schöne Grüße!
Tobias
[0] http://en.wikipedia.org/wiki/Map_(higher-order_function)
[1] http://en.wikipedia.org/wiki/Fold_(higher-order_function)
An der Stelle ist ja schon klar, dass @_ nur ein Element hat und keine
Arrayreferenz ist, also reicht ein
return uc($_[0]);
Ist mir eben erst aufgefallen.