Gustl: array ... sort ... zahlen ... problem ...

Hi, ich komme nicht weiter. Der @Array ist so aufgebaut:

Value: Datensatz 1 $_ = 100;300;Hans;Im;Glück;Text;Irgendwas ...
Value: Datensatz 2 $_ = 1023;856;Sepp;Im;Grund;Text;Irgendwas ...

und so weiter ...

ich habe nun die Aufgabe, so ca. 1500 im Array gespeicherten Datensätze absteigend nach Nummern zu ordnen.

sort klappt nicht , klar, ascii

so:
my @erg_sort = sort(Num_Sort @daten);
sub Num_Sort { if($a < $b) { return -1; } elsif($a == $b) { return 0; } else { return 1; } }

gehts auch nicht, das script bleibt einfach nur hängen und liefert nix zurück.

diese möglichkeit funzt nur, wenn im array pro datensatz NUR EINE nummer steht. bei mir steht aber in $_ wie oben beschrieben.

weiss jemand ne lösung ?

  1. Hi,
    wie kommen denn die daten in das array? ließt du die aus einer DB? wenn ja welches DBMS?

    MfG

    1. Lese aus einer csv so ein ...

      open(INSERAT, "<../members/$_/anzeigen.dat");
      flock(INSERAT, LOCK_SH);
        while(<INSERAT>)
      {
      $_ =~ s/[\n]//g; $_ =~ s/<br>/ /gi; push ( @all, $_ );
      }
        flock(INSERAT, LOCK_UN); close(INSERAT);

  2. Hallo Gustl

    Hi, ich komme nicht weiter. Der @Array ist so aufgebaut:

    Value: Datensatz 1 $_ = 100;300;Hans;Im;Glück;Text;Irgendwas ...
    Value: Datensatz 2 $_ = 1023;856;Sepp;Im;Grund;Text;Irgendwas ...

    so:
    my @erg_sort = sort(Num_Sort @daten);
    sub Num_Sort { if($a < $b) { return -1; } elsif($a == $b) { return 0; } else { return 1; } }

    Naja, du musst den Datensatz noch splitten, da du Strings nicht so vergleichen kannst. Vielleicht hilft dir die Schwartzsche Transformation.

    Struppi.

  3. Hallo,

    ich habe nun die Aufgabe, so ca. 1500 im Array gespeicherten Datensätze absteigend nach Nummern zu ordnen.
    weiss jemand ne lösung ?

    Hast Du
    http://perldoc.perl.org/perlfaq4.html#How-do-I-sort-an-array-by--anything--
    bzw.
    http://perldoc.perl.org/functions/sort.html schon gelesen?

    Grüße
      Klaus

    1. Hallo,

      Und dann gibts da noch http://search.cpan.org/~jzucker/DBD-CSV-0.22/.

      Grüße
        Klaus

  4. Hallo,

    weiss jemand ne lösung ?

    Du willst beide Zahlen (100;300 usw) in die Sortierung einbeziehen? Versuch mal das:

    @daten =("100;300;Hans;Im;Glück;Text;Irgendwas","1023;856;Sepp;Im;Grund;Text;Irgendwas");

    @sortiert = map { $_ -> [0]}
    sort {  $b->[0] <=> $a->[0] || $b->[1] <=> $a->[1] }
    map { [ $_, (split/;/)[0,1] ] } @daten;

    foreach (@sortiert) {
    @zeile = split(/;/, $_);
    print "$zeile[0] - $zeile[1] - $zeile[2] - $zeile[3] - $zeile[4] - $zeile[5]<br>\n"
    }

    Wenn Du $b $a vertauschst ist die Sortierung wieder andersrum.

    Gruß Helmut

    1. Du willst beide Zahlen (100;300 usw) in die Sortierung einbeziehen? Versuch mal das:
      @daten =("100;300;Hans;Im;Glück;Text;Irgendwas","1023;856;Sepp;Im;Grund;Text;Irgendwas");

      @sortiert = map { $_ -> [0]}
      sort {  $b->[0] <=> $a->[0] || $b->[1] <=> $a->[1] }
      map { [ $_, (split/;/)[0,1] ] } @daten;

      Hi Helmut, will ich nicht, sondern nur die erste Zahl

      hab umgebaut:

      @sortiert = map { $_ -> [0]}
      sort {  $b->[0] <=> $a->[0] }
      map { [ $_, (split/;/)[0] ] } @daten;

      das einzige ist, ich krieg nen script-fehler nach ein paar minuten zurückgeliefert

      1. Du willst beide Zahlen (100;300 usw) in die Sortierung einbeziehen? Versuch mal das:
        @daten =("100;300;Hans;Im;Glück;Text;Irgendwas","1023;856;Sepp;Im;Grund;Text;Irgendwas");

        @sortiert = map { $_ -> [0]}
        sort {  $b->[0] <=> $a->[0] || $b->[1] <=> $a->[1] }
        map { [ $_, (split/;/)[0,1] ] } @daten;

        Hi Helmut, will ich nicht, sondern nur die erste Zahl

        hab umgebaut:

        @sortiert = map { $_ -> [0]}
        sort {  $b->[0] <=> $a->[0] }
        map { [ $_, (split/;/)[0] ] } @daten;

        Das ist falsch.
        Der Index bezieht sich auf [ $_, split ] d.h. [0] ist der pure Datensatz. Das Orginal war aber auch schon falsch, das soll übrigens das von mir genante sein: die Schwartzsche Transformation, ein wenig danach suchen und du könntest es verstehen.

        Du willst:

        #!/usr/bin/perl -w

        use strict;
        use Data::Dumper;
        chomp( my @daten = <DATA> );

        my @sortiert = map { $_->[0]}
        sort {  $b->[1] <=> $a->[1]  }
        map { [ $_, (split/;/)[0,1] ] } @daten;

        print Dumper @sortiert;

        __DATA__
        1000;300;Hans;Im;Glück;Text;Irgendwas ...
        1023;856;Sepp;Im;Grund;Text;Irgendwas ...
        1001;300;Hans;Im;Glück;Text;Irgendwas ...

        Falls du umgekehrt sortieren willst musst du a und b vertauschen.

        das einzige ist, ich krieg nen script-fehler nach ein paar minuten zurückgeliefert

        Struppi.

        1. Das ist falsch.
          Der Index bezieht sich auf [ $_, split ] d.h. [0] ist der pure Datensatz.

          JA JA JA  STRUPPI Du bist der grösste. Jetza hab ichs kapiert.

          Es funzt wie der Blitz.

          Vielen, Vielen Dank !

        2. Tag Struppi.

          @sortiert = map { $_ -> [0]}
          sort {  $b->[0] <=> $a->[0] }
          map { [ $_, (split/;/)[0] ] } @daten;
          Das ist falsch.

          Richtig. Der Fehler liegt allerdings nicht in den map-Anweisungen, sondern in der sort-Anweisung (ich bin mir nicht sicher, dass du das so gemeint hast).

          Du willst:
          [...]
          my @sortiert = map { $_->[0]}
          sort {  $b->[1] <=> $a->[1]  }
          map { [ $_, (split/;/)[0,1] ] } @daten;

          Wozu sollte er die ersten beiden Teile extrahieren wollen, wenn er doch nur nach dem ersten Teil sortieren will? Richtig wäre es so:

          my @sortiert = map  { $_->[0] }  
                         sort { $b->[1] <=> $a->[1] }  
                         map  { [ $_, (split/;/)[0] ] } @daten;
          

          Es ginge übrigens auch ohne Schwartzsche Transformation:

          my @sortiert = sort { substr($b, 0, index($b, ";")+1) <=> substr($a, 0, index($a, ";")+1) } @Array;

          Allerdings zeigt das Beispielskript, dass die Schwartzsche Transformation schneller ist.

          @Gustl: Dein Code konnte mit "<=>" nicht funktionieren, da die perleigene Typumwandlung String->Integer daran scheitern musste, dass deine Array-Elemente nicht-numerische Zeichen enthielten. Nur zur Ergänzung: Siechfred versucht, die Schwartzsche Transformation zu erklären ;-)

          Siechfred

          --
          «Ich liebe euch doch alle!»
          1. Guten Morgen. Es ist jetzt 1 Uhr UTC

            Hi Siechfred !

            my @sortiert = map { $_->[0]}
            sort {  $b->[1] <=> $a->[1]  }
            map { [ $_, (split/;/)[0,1] ] } @daten;

            So funkts. Ich weiss noch nicht ganz warum,
            aber das ist ja egal :-)))

            Hätte Gott den PC erfunden, hätte er Bill Gates garantiert nicht daran rumfummeln lassen.

            --
            G. DAVID
  5. Vielen Dank für die vielen Tipps !

    Hab allerhand probiert, gelesen, experimentiert.

    Wenn ich cmp vergleiche, ratsch ist das Ergebnis da, natürlich falsch, ist ja ascii. Die tausender stehen voran.

    Aber sobald ich <=> vergleiche, egal in welcher Routine, HANGUP !
    Als wären meine Zahlen keine Zahlen ...

    Ich hab die CSV auch schon nach leerzeichen oder anderen ungewöhnlichen vorkommnissen durchsucht und sitze nun schon 5 stunden davor >> nix wirds