marcus: sortieren nach prioritaet

hallo,

ich moechte im u.g. code ein array nach "date" sortieren, was auch klappt. nun moechte ich die sortierung noch nach "time" erweitern, soll heissen: erst nach date sortieren und gleichzeitig auch nach "time" wenn mehrere "date" eintraege gleich sind?
 wie kann man das denn am geschickesten machen?

danke fuer die hilfe!
marcus

@sorted = ();
@data = ();
foreach $line (@data_unsorted) {
        ($id,$headline,$date,$time,$location,$jhg,$email,$description) = split(/\|\/,$line);
        push(@sorted, {
                id => $id,
                headline => $headline,
                date => $date,
                time => $time,
                location => $location,
                jhg => $jhg,
                email => $email,
                description => $description
        });
}
for $sorted (sort { ($::a->{date}) cmp ($::b->{date}) } @sorted) {
        $line = "$$sorted{'id'}*|*$$sorted{'headline'}*|*$$sorted{'date'}*|*$$sorted{'time'}*|*$$sorted{'location'}*|*$$sorted{'jhg'}*|*$$sorted{'email'}*|*$$sorted{'description'}\n";
        push(@data,$line);
}

  1. Halihallo

    ich moechte im u.g. code ein array nach "date" sortieren, was auch klappt. nun moechte ich die sortierung noch nach "time" erweitern, soll heissen: erst nach date sortieren und gleichzeitig auch nach "time" wenn mehrere "date" eintraege gleich sind?
    wie kann man das denn am geschickesten machen?

    Ich würde die Date und Time Angaben in eine packen: UNIX-Timestamp. Dann kannst du nummerisch sortieren (ist IMO sogar viel schneller, als Stringoperationen) und du hast gleich nach Datum _UND_ Zeit sortiert.

    im Detail:

    Wie ist date und time bei dir aufgebaut?

    date: "yyyy-mm-dd" und time: "hh:mm:ss"?
    =>

    my ($y, $mo, $d) = split( /-/, $date );
    my ($h, $mi, $s) = split( /:/, $time );

    $mo--; $y-=1900;

    use Time::Local qw(timelocal);
    my $timestamp = timelocal($s, $mi, $h, $d, $mo, $y);

    push ..., { ..., Timestamp=>$timestamp, ...}

    nacher sort {$::a->{timestamp} <=> $::b->{timestamp}}

    Viele Grüsse

    Philipp

    PS: Oder hab ich was falsch verstanden?

    1. Halihallo

      ich moechte im u.g. code ein array nach "date" sortieren, was auch klappt. nun moechte ich die sortierung noch nach "time" erweitern, soll heissen: erst nach date sortieren und gleichzeitig auch nach "time" wenn mehrere "date" eintraege gleich sind?
      wie kann man das denn am geschickesten machen?

      Ich würde die Date und Time Angaben in eine packen: UNIX-Timestamp. Dann kannst du nummerisch sortieren (ist IMO sogar viel schneller, als Stringoperationen) und du hast gleich nach Datum _UND_ Zeit sortiert.

      Moin Moin !

      Für's Archiv:

      In diesem speziellen Fall würde ich Dir zustimmen, C-Time oder Vergleichbares ist wesentlich effektiver.

      Wenn Du aber etwas exotischere Anforderungen hast (erst nach Name (case-insensitiv), dann nach Vorname (case-sensitiv), dann nach Datum, dann nach absteigender Größe), kommst Du nicht um eine etwas aufwändigere Vergleichsfunktion herum:

      my @unsorted=(
       { name => 'Demo', firstname => 'bla', date => 12345, size => 42 },
       ...
      );

      sub by_name_date_and_size
      {
          return (
               lc($a->{'name'}) cmp lc($b->{'name'})  # name, case-ins.
                                ||
              $a->{'firstname'} cmp $b->{'firstname'} # firstname, case-sens
                                ||
                   $a->{'date'} <=> $b->{'date'} # datum, numerisch
                                ||
                   $b->{'size'} <=> $a->{'size'} # size, numerisch, absteigend
          );
      }

      my @sorted=sort by_name_date_and_size @unsorted;

      Alles aus dem Kopf frei nach irgendeinem guten Perl-Buch (oder sogar der Doku ?).

      Alexander

      1. Halihallo Alexander und marcus

        Für's Archiv:

        Na, so schnell wird der Thread noch nicht gefressen ;-)

        Wenn Du aber etwas exotischere Anforderungen hast (erst nach Name (case-insensitiv), dann nach Vorname (case-sensitiv), dann nach Datum, dann nach absteigender Größe), kommst Du nicht um eine etwas aufwändigere Vergleichsfunktion herum:

        [...riesen-sort...]

        Danke für die Beispiele von euch beiden. Ich hatte keine Ahnung, dass man so komplex mit sort sortieren kann (das liegt wohl daran, dass ich noch nie vor diese Aufgabe gestellt wurde, bzw. sie mit selber programmierten algos löste). Ich habe zwar die Doku zu sort gelesen, aber wohl eben nicht gelesen, sondern nach 10 Zeilen nur noch überflogen ;)

        Viele (MENSCHELEI) Grüsse

        Philipp