Simon: Array in ein Hash wandeln.

Hallo,

ich habe folgende Frage.

Ich bekomme in einem %hash u.a. ein Feld 'breadcrumb' übergeben.

Je nach aufrufendem Skript sieht die Ausgabe von print Dumper ( $hash{'breadcrumb'} ); so ...

$VAR1 = { '1' => { '1' => { 'categoryName' => 'Freizeit & Sport', 'categoryUrl' => 'books.pl?c=4' }, '2' => { 'categoryUrl' => 'books.pl?c=9', 'categoryName' => 'Fahrräder' } } };

oder so ...

$VAR1 = [ { 'categoryName' => 'Fragen und Antworten', 'categoryUrl' => 'helpdesk.pl' }, { 'categoryUrl' => 'helpdesk.pl?c=1', 'categoryName' => 'Allgemeines' } ];

aus.

Ich würde gern den zweiten Fall in den ersten überführen.

Also $hash{'breadcrumb'} soll immer dann, wenn die Referenz von $hash{'breadcrumb'} ein 'ARRAY' ist, nach dem Konvertieren so aussehen:

$VAR1 = { '1' => { '1' => { 'categoryName' => 'Fragen und Antworten', 'categoryUrl' => 'helpdesk.pl' }, '2' => { 'categoryUrl' => 'helpdesk.pl?c=9', 'categoryName' => 'Allgemeines' } } };

Ist eine solche Konvertierung unkompliziert möglich?

Danke Simon

  1. hallo

    Ist eine solche Konvertierung unkompliziert möglich?

    ungetestet

    my $n=0;
    my $newhashref={};
    map{ $newhashref->{++$n} = $_ } @youroldARRAY;
    
  2. hi

    Also $hash{'breadcrumb'} soll immer dann, wenn die Referenz von $hash{'breadcrumb'} ein 'ARRAY' ist, nach dem Konvertieren so aussehen:

    Das kannst abfragen per ref $ref Siehe perldoc -f ref

    Und was die Konvertierung betrifft, machs mit each():

    my @ar = qw(eins zwei drei);
    while( my($i, $v) = each @ar ){
        print "$i => $v\n";
        shift;
    }
    
    gibt aus:
    0 => eins
    1 => zwei
    2 => drei
    
    

    das liefert index und value. MfG

    1. Hallo,

      kann ich kurz nachfragen, ob mein Array, was in $hash{'breadcrumb'} gespeichert ist, gleichbedeutend mit einem @ar in deinem Beispiel ist?

      Also kann ich durch $hash{'breadcrumb'} auch mit einem foreach durchgehen?

      Danke!

      1. Guck Beispiel

        # gegeben
        my %hash = ();
        $hash{breadcrumb}  = [ 
            { 
                'categoryName' => 'Fragen und Antworten', 
                'categoryUrl' => 'helpdesk.pl' 
            }, 
            {
                'categoryUrl' => 'helpdesk.pl?c=1', 
                'categoryName' => 'Allgemeines' 
            }
        ];
        
        if( ref $hash{breadcrumb} eq 'ARRAY' ){
            print "In Hash umwandeln\n";
            
            my $tmp = {}; # hashref
            # wegen der besseren Lesbarkeit
            my @ar = @{$hash{breadcrumb}};
            while( my($i, $href) = each @ar ){
                my $k = 1 + $i;
                $tmp->{$k} = $href;
                shift;
            }
            $hash{breadcrumb} = ();
            $hash{breadcrumb}{1} = $tmp;
            print Dumper $hash{breadcrumb}, $tmp;
        }
        else{
            print "Kann so bleiben\n";
        }
        

        Der Umgang mit Referenzen ist Übungssache!

        MfG

        1. Der Umgang mit Referenzen ist Übungssache!

          In Perl definitiv, weil extrem hässlich da 😉

          1. Der Umgang mit Referenzen ist Übungssache!

            In Perl definitiv, weil extrem hässlich da 😉

            Die Lesbarkeit kann man übrigens verbessern indem man

            1. nur einen Pfeil notiert
            2. in den {} die Stringbegrenzer weglässst
            # 1
            $ref = $h->{'foo'}->{'bar'}->{'baz'};
            $ref = $h->{'foo'}{'bar'}{'baz'};
            
            # 2
            $ref = $h->{foo}{bar}{baz};
            

            MfG

            1. Vielen, vielen Dank.

              Das versuche ich jetzt mal bei mir zu integrieren.

              PS: Und das mit dem "hässlich" ... ja. Zumindest recht kompliziert :(

              :)

              1. Vielen, vielen Dank.

                Keine Uhrsache.

                Das versuche ich jetzt mal bei mir zu integrieren.

                PS: Und das mit dem "hässlich" ... ja. Zumindest recht kompliziert :(

                Oh, guckst Du mal PHP oder JavaScript:

                $inf['foo']['bar']['baz'];
                

                da musst du nämlich alles quoten. Nicht nur daß es den Code unleserlich macht, es nervt auch.

                MfG

            2. Die Lesbarkeit kann man übrigens verbessern indem man

              1. nur einen Pfeil notiert
              2. in den {} die Stringbegrenzer weglässst
              $ref = $h->{foo}{bar}{baz};
              

              JavaScript:

              ref = h.foo.bar.baz;
              

              Nur wollte ich darauf überhaupt nicht hinaus. Das syntaktische Rumgeraffel in Perl ist nervig, um aus der Referenz z.B. den eigentlichen Array/Hash zu iterieren.

              1. Das syntaktische Rumgeraffel in Perl ist nervig, um aus der Referenz z.B. den eigentlichen Array/Hash zu iterieren.

                Gerade bei Referenzen kannst Du doch prima abkürzen, eben weil es Referenzen sind:

                # Array in baz überschreiben
                  my $baz = $ref->{foo}{bar}{baz};
                  $baz = [1,2,3];
                
                # iterieren
                  each @$baz;
                

                Aber Du hast recht, ich kenne Programmierer die da jedesmal den ganzen Schwanz $ref->{foo}{bar}{baz} mitschleppen.

                Und auch Packages Lookups wie package A::B::C::D::E::F::Foo::Bar::Baz ihren Angestellten zumuten anstatt einmal den use lib qw(/A/B/C/D/E/F) Pfad richtig zu setzen.

                Wers braucht.

          2. Der Umgang mit Referenzen ist Übungssache!

            In Perl definitiv, weil extrem hässlich da 😉

            Ich hatte mal einen PHP Kollegen der hat keine 30 Minuten gebraucht, um Perl Referenzen zu verstehen. Wobei das Beispiel was ich da grade am Wickel hatte einige MBs an Daten aus ca 20 Tabellen einer Oracle DB referenzierte, samt DB Struktur.

            Das Schöne an Referenzen ist ja, daß man beim Arbeiten mit Daten in tiefer geschachtelten Datenstrukturen nicht den ganzen Stamm von der Wurzel an mitschleppen muss sondern mit einem einzigen Scalar eben nur den Zweig referenziert.

            Also mal ne halbe Stunde intensiv damit befasst und dann sitzt sowas.