Steffen: 2 Dimensionales HashArray

Hallo Forumsgemeinde,

ich hab derzeit ein Problem mit einem 2Dimensionalen HashArray.
und zwar will ich einen Beispieldatensatz wie den folgenden einlesen

ID|NAME|WERT
1|Egon|34
4|Franz|23
8|Jürgen|9
13|Kurt|1

ich würde das eigentlich Zeilenweise mit Push machen
push(@DATEN, { 'id' => $1, 'name' => $2, 'value' => $3 });

jedoch besteht dann das Problem das ich natürlich meinen Wert im späteren Skript direkt mit der ID aufrufen will nicht ausgeliefert bekomme sondern nen andern:
$DATEN[$i]->{'name'}  wenn ich für $i die ID 1 annehme bekomm ich ja den Wert der ID 4...

Ich hab mich dann mit Zeigern probiert jedoch bekomm ich das immer nur richtig hin wenn ich eindimensional Arbeite ( halt nur zum Test)

nun hab ich mich mit der Methode probiert ohne Push
 und einfach zugeordnet für jede Zeile :  $DATEN[$i]->{'name'} = $2;
jedoch bleiben dann natürlich im Hasharray die Felder 0,2,3,5, etc. undefiniert und ich bekomme Probleme beim Sortieren...

Kann mir jemand helfen...
Hab ich nen komplett Falschen Ansatz ?

Gruß
Steffen

  1. Hallo Forumsgemeinde,

    ich hab derzeit ein Problem mit einem 2Dimensionalen HashArray.
    und zwar will ich einen Beispieldatensatz wie den folgenden einlesen

    ID|NAME|WERT
    1|Egon|34
    4|Franz|23
    8|Jürgen|9
    13|Kurt|1

    ich würde das eigentlich Zeilenweise mit Push machen
    push(@DATEN, { 'id' => $1, 'name' => $2, 'value' => $3 });

    jedoch besteht dann das Problem das ich natürlich meinen Wert im späteren Skript direkt mit der ID aufrufen will nicht ausgeliefert bekomme sondern nen andern:
    $DATEN[$i]->{'name'}  wenn ich für $i die ID 1 annehme bekomm ich ja den Wert der ID 4...

    Ich hab mich dann mit Zeigern probiert jedoch bekomm ich das immer nur richtig hin wenn ich eindimensional Arbeite ( halt nur zum Test)

    nun hab ich mich mit der Methode probiert ohne Push
    und einfach zugeordnet für jede Zeile :  $DATEN[$i]->{'name'} = $2;
    jedoch bleiben dann natürlich im Hasharray die Felder 0,2,3,5, etc. undefiniert und ich bekomme Probleme beim Sortieren...

    Kann mir jemand helfen...
    Hab ich nen komplett Falschen Ansatz ?

    Gruß
    Steffen

    Hallo Steffen,

    versuch es mal so:

    #!perl

    my $datei = {};
    while (<DATA>){
     chomp;
     my ($id,$name,$wert) = split /|/;
     $datei->{$id}->{'name'} = $name;
     $datei->{$id}->{'wert'} = $wert;
    }
    print $datei->{'4'}->{'name'};
    __DATA__
    1|Egon|34
    4|Franz|23
    8|Jürgen|9
    13|Kurt|1

    Gruß
    Roland

    1. Hallo Roland,

      versuch es mal so:

      #!perl

      my $datei = {};
      while (<DATA>){
      chomp;
      my ($id,$name,$wert) = split /|/;
      $datei->{$id}->{'name'} = $name;
      $datei->{$id}->{'wert'} = $wert;
      }
      print $datei->{'4'}->{'name'};
      __DATA__
      1|Egon|34
      4|Franz|23
      8|Jürgen|9
      13|Kurt|1

      Danke erstemal für den Tip,
      bisher habe ich mein HashArray dann immer mit
      $DATEN = sort { $a->{'value'} <=> $b->{'value'} } $DATEN
      sortiert...

      wie muss ich jetzt herangehn ?
      Es is doch jetzt nen Unterschied ?! da es doch jetzt nur nen 2Dimensionales Hash is....

      Torzdem schonmal Danke...

      Gruß
      Steffen

      1. ich nochmal...

        zum Sortieren will ich nun auf die Keys des Hashes zugreifen...
        jedoch gibt es bei mir das Hash %datei garnicht...
        Des macht aber Stutzig denn ich deklariere ja das Hash extra noch ganz am Anfang des Scriptes und füge dann wie von dir beschrieben die einzelen Werte hinzu...
         ich hab in der Perldoc jetzt auch noch nix gefunden...
        (falls ich überhaupt an der korrekten stelle suche *g* )
        *grübel*

        Gruß
        Steffen

        1. ich nochmal...

          zum Sortieren will ich nun auf die Keys des Hashes zugreifen...
          jedoch gibt es bei mir das Hash %datei garnicht...
          Des macht aber Stutzig denn ich deklariere ja das Hash extra noch ganz am Anfang des Scriptes und füge dann wie von dir beschrieben die einzelen Werte hinzu...
          ich hab in der Perldoc jetzt auch noch nix gefunden...
          (falls ich überhaupt an der korrekten stelle suche *g* )
          *grübel*

          Gruß
          Steffen

          Hallo Steffen,

          es gibt da zwei Loesungen

          1. Loesung mit 2 Dim. Hash,
          ------------------------------------------------------------------
          #!perl
          #%hash_datei = (
          #                1 => {
          #                       name => "Egon",
          #                       wert => 34,
          #                     },
          #              )
          my %hash_datei;
          while ( <DATA> ){
           chomp;
           my ($id,$name,$wert) = split /|/;
           $hash_datei{$id}{'name'} = $name;
           $hash_datei{$id}{'wert'} = $wert;
          }
          my @all_id   = sort  keys %hash_datei;
          print "@all_id\n";
          print "#" x 60 , "\n";

          #Ausgabe vom hash_datei ; sort nach id
          foreach my $id ( sort {$a <=> $b} keys %hash_datei ) {
               print "$id: { ";
               for my $zeile ( sort keys %{ $hash_datei{$id} } ) {
                   print "$zeile=$hash_datei{$id}{$zeile} ";
               }
               print "}\n";
          }
          __DATA__
          1|Egon|34
          4|Franz|23
          8|Jurgen|9
          13|Kurt|1
          -------------------------------------------------------------------

          2. Loesung mit Referenzen, das ist mein Vorschlag
          -------------------------------------------------------------------
          #!perl
          #Loesung mit Referenzen
          my $ref_datei;
          while ( <DATA> ){
           chomp;
           my ($id,$name,$wert) = split /|/;
           $ref_datei->{$id}->{'name'} = $name;
           $ref_datei->{$id}->{'wert'} = $wert;
          }

          print "#" x 60 , "\n";

          my @all_id   = sort { $a <=> $b } keys %{$ref_datei};
          my @all_name = map  { $ref_datei->{$_}->{name} }  keys %{$ref_datei} ;
          my @all_wert = map  { $ref_datei->{$_}->{wert} }  keys %{$ref_datei} ;
          print "@all_id\n@all_name\n@all_wert\n";

          print "#" x 60 , "\n" x 3 , "sort nach id\n";
          foreach ( keys %{$ref_datei} ){
           print "$_ name = $ref_datei->{$_}{name}  wert  =$ref_datei->{$_}->{wert}\n";
          }

          print "#" x 60 , "\n" x 3 , "sort nach wert\n";
          foreach ( sort { $a->{'wert'} <=> $b->{'wert'} } keys %{$ref_datei} ){
           print "$_ name = $ref_datei->{$_}{name}  wert  =$ref_datei->{$_}->{wert}\n";
          }

          print "#" x 60 , "\n" x 3 , "sort nach name\n";
          foreach ( sort { $a->{'name'} cmp $b->{'name'} } keys %{$ref_datei} ){
           print "$_ name = $ref_datei->{$_}{name}  wert  =$ref_datei->{$_}->{wert}\n";
          }
          __DATA__
          1|Egon|34
          4|Franz|23
          8|Jurgen|9
          13|Kurt|1
          ------------------------------------------------------------------

          mehr Infos unter perldsc.

          Ich benutzt nur noch Referenzen also "my $tmp = {};", das ist kein Hash.

          Bye
          Roland

      2. use Mosche;

        $datei->{$id}->{'name'} = $name;
        $datei->{$id}->{'wert'} = $wert;

        Es is doch jetzt nen Unterschied ?! da es doch jetzt nur nen 2Dimensionales Hash is....

        Du kannst das ganze auch mit nem Array bewerkstelligen  es wird nur ineffizient, wenn es grosse Lücken zwischen den einzelnen IDs gibt:
        Das würdest du dann so machen

        while(<DATA>) {
          my ($id, $a, $b) = split /|/;
          $Daten[$id] = { name => $a, wert => $b };
        }

        aber, wie gesagt: dass _kann_ ineffizient sein, hat aber Vorteile, wenn du sortieren willst (weil ein Array (im Ggs. zum Hash) bereits sortiert vorliegt.)

        use Tschoe qw(Matti);

        1. Hallo,

          Du kannst das ganze auch mit nem Array bewerkstelligen  es wird nur ineffizient, wenn es grosse Lücken zwischen den einzelnen IDs gibt:
          Das würdest du dann so machen

          while(<DATA>) {
            my ($id, $a, $b) = split /|/;
            $Daten[$id] = { name => $a, wert => $b };
          }

          aber, wie gesagt: dass _kann_ ineffizient sein, hat aber Vorteile, wenn du sortieren willst (weil ein Array (im Ggs. zum Hash) bereits sortiert vorliegt.)

          das is ja genau das Problem was ich doch geschrieben hab...
          wenn ich das so verwende kann ich ja meine Daten dann nicht Sortieren, da die Lücken halt undefiniert sind... dann schmiert mir das Script ab...