$xNeTworKx: Hash nach Werten sortieren

Hallo,
ich weis nicht warum, aber es gelingt mir einfach nicht einen Hash nach den Werten anstatt den Schlüsseln zu sortieren.
Das folgende kleine Script erzeugt eine Vielposterstatistik meines Boards, wobei der der am Meisten postet ganz oben stehen soll.
Das Script funktioniert tadellos, wenn ich nach den Schlüssel sortiere.

foreach (sort {$a cmp $b} keys %namen)    {
print "$_ : $namen{$_}<br>\n";
}

Will ich aber nach den Werten sortieren zB :

foreach (sort {$a <=> $b} values %namen)    {
print "$_ : $namen{$_}<br>\n";
}

bekomme ich einen "use of uninitialized value .." in der Zeile :
print "$_ : $namen{$_}<br>\n";

Der Schlüssel ist auf jeden Fall eine Zahl, hier das Script :

#!/usr/bin/perl -w

use strict;

my %namen = ();

opendir (DIR,'messages') or die "Cant open 'messages' : $!\n";
while (defined($_ = readdir DIR))   {
        if ($_ =~ /^\d+?.cgi$/)    {
                open (FILE,"messages/$_") or die "Cant open $_ : $!\n";
        local $/;
        my $inhalt = <FILE>;
        while ($inhalt =~ /<name>(.+?)</name>/sg)    {
        my $name = $1;
                         if (exists $namen{$name})   {
   $namen{$name}++;
   }   else   {
   $namen{$name} = 1;
   }
        }
        close FILE;
        }
}
closedir DIR;

print "Content-type:text/html\n\n";
foreach (sort {$a <=> $b} values %namen)    {
print "$_ : $namen{$_}<br>\n";

  1. Halihallo $xNeTworKx

    Will ich aber nach den Werten sortieren zB :

    foreach (sort {$a <=> $b} values %namen)    {
    print "$_ : $namen{$_}<br>\n";
    }

    bekomme ich einen "use of uninitialized value .." in der Zeile :
    print "$_ : $namen{$_}<br>\n";

    Ja, das ist auch richtig so, denn: du sortierst, wie gewollt, die _Werte_ des Hashes und
    durchläufst dann die _Werte_ in der foreach-Schleife. Dann liest du jedoch $namen{$_} ein
    und das ist dann natürlich meistens uninitiailisiert (es sei denn, der _Wert_ gäbe es
    auch als _Key_ im Hash). Du müsstest den Hash umdrehen (im Sinne von Wert=Name und
    Name=Wert) und dann nach den Keys (die vorher Values waren) sortieren und iterieren.
    Problem ist nur, dass du natürlich gleichwertige values verlierst, aber das lässt sich
    ja umgehen (eg. Hash-Value ist ein Array).

    Viele Grüsse

    Philipp

    1. Hallo,

      danke für den Tipp, aber da wären wir dann wieder bei verschachtelten Datenstrukturen, wobei ich mich leider nicht auskenne.
      Gibt es vielleicht irgendwo ein gutes Tut., wo ich mich darüber besser informieren kann ?

      $xNeTworKx.

      1. Halihallo $xNeTworKx

        danke für den Tipp, aber da wären wir dann wieder bei verschachtelten Datenstrukturen, wobei ich mich leider nicht auskenne.
        Gibt es vielleicht irgendwo ein gutes Tut., wo ich mich darüber besser informieren kann ?

        perldoc perlreftut
        perldoc perldata
        perldoc perllol

        wären da zu empfehlen, andere (einfachere? - wobei ich die gut verständlich finde) sind
        mir grad nicht bekannt.

        Viele Grüsse

        Philipp

  2. use Mosche;

    foreach (sort {$a cmp $b} keys %namen)    {
    print "$_ : $namen{$_}<br>\n";
    }

    Will ich aber nach den Werten sortieren zB :

    foreach (sort {$a <=> $b} values %namen)    {

    Neben dem Tip von Philipp vielleicht nich folgendes:

    foreach (sort  { $namen{$a} <=> $namen{$b} } keys %namen) {
      ...
    }

    use Tschoe qw(Matti);

    --
      Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
    1. Hallo,

      foreach (sort  { $namen{$a} <=> $namen{$b} } keys %namen) {

      Genau das, was ich brauche. Danke, jetzt klappts.

      $xNeTworKx.