[Munich-pm] sort mit curried function
Harald Joerg
harald.joerg at ts.fujitsu.com
Mo Nov 19 03:40:33 PST 2012
Hallo Robert,
Dass Deine Überlegungen nicht funktionieren, liegt daran, dass
sort SUBNAME LIST syntaktisch etwas "eingeschränkt" ist.
Es geht aber, mit einfacherem bykey, wie folgt:
----------------------------------------------------------------------
#!/usr/bin/perl -w
use strict;
my @liste = ({ x => 1, y => 4}, {x => 3, y => 2});
foreach my $h (sort {bykey('x')} @liste){
print $h->{x}, $h->{y}, "\n";
}
sub bykey {
my $key = shift;
return($a->{$key} <=> $b->{$key});
}
----------------------------------------------------------------------
* Anstelle von sort SUBNAME LIST verwende ich sort BLOCK LIST,
das frisst der Parser leichter.
* In bykey sind $a und $b direkt verfügbar, das sind package globals
(@Marek: Die muss man also nicht übergeben). Der Code ist nicht
reentrant, es wäre also unklug, innerhalb von bykey nochmal einen
sort-Aufruf zu haben (ginge auch, aber nur über sort mit Prototypes).
Es ist aber nicht nötig, eine eigene Subroutine zu erzeugen.
(@Roderich: Geht nicht - gibt's nicht :))
--
Cheers,
haj
"Robert C. Helling" <helling at lmu.de> writes:
> Hallo,
>
> ich stehe grade mal wieder auf dem Schlauch. Ich habe eine Liste mit
> Hashreferenzen, wobei die Hashes mehrere Felder vom gleichen Typ haben.
> Nun moechte ich gerne die Liste sortieren anhand jeweils eines Feldes des
> Hashes. Die Vergleichsfunktion ist etwas kompliziert. Daher will ich sie
> nicht fuer jedes Hashfeld neu schreiben, sondern mach lieber eine
> gemeinsame Vergleichsfunktion, die den Namen des Feldes bekommt und dann
> entsprechend gecurried wird. Schematisch wie in diesem Beispiel:
>
> #!/usr/bin/perl -w
>
> use strict;
>
> my @liste = ({ x => 1, y => 4}, {x => 3, y => 2});
>
>
> my $byx = &bykey('x');
>
> foreach my $h (sort $byx @liste){
> print $h->{x}, $h->{y}, "\n";
> }
>
> sub bykey {
> my $key = shift;
>
> return(sub {$a->{$key} <=> $b->{$key}});
> }
>
>
> Das funktioniert so. Meine Frage ist nun: Wie komme ich ohne die
> Dummyvariable $byx aus? Ich habe zB schon probiert
>
> foreach my $h (sort &&bykey('x') @liste){
>
> aber das gibt einen Syntaxerror. Auch aehnliche Versionen mit weniger &'s
> und mehr oder wenigen Klammern verschiedenen Typs habe ich probiert, aber
> nichts davon funktionierte.
>
> Wer erleuchtet mich?
>
> Viele Gruesse
> Robert
Mehr Informationen über die Mailingliste Munich-pm