Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Multidimensional Hash losts entrys

by sandorado (Initiate)
on Aug 13, 2014 at 13:04 UTC ( #1097274=perlquestion: print w/replies, xml ) Need Help??

sandorado has asked for the wisdom of the Perl Monks concerning the following question:

I have a Hash within an if-declaration (which is also in an foreach Loop). Outside of this loop, there is only the last entry of the hash left. Why? And how can I receive the other 25 entries of the hash outside the declartion? I really don't know, why this is happening. $nodeset finds the right node in the document, which is the inputfile I want to check
foreach my $node ($nodeset->get_nodelist) { #this line below is just for checking, what can be found within +the nodelist my $a = $node->getAttribute('a'); my $b = $node->getAttribute('b'); my $c= $node->getAttribute('c'); if((defined $a) && (defined $b) && (defined $c)) { @arr_a = split (/ /, $a); @arr_b = split (/ /, $b); @arr_c = split (/ /, $c); }else{ print "Warning! \n"; } %complete =( @arr_a=>[@arr_b, @arr_c], ); } print Dumper %complete;
--> but here is the Problem. Outside of the Loop, there is only the last hash-element left. I hope someone can help me and explain me whats the error. regards

Replies are listed 'Best First'.
Re: Multidimensional Hash losts entrys
by choroba (Archbishop) on Aug 13, 2014 at 13:26 UTC
    You're overwriting the hash in every iteration. You can assign to a hash slice, fortunately:
    @complete{@arr_a} = ...;

    It's not clear what exactly you want to assign, though. Does the following work for you?

    #!/usr/bin/perl use warnings; use strict; use Data::Dumper; use XML::LibXML; my $xml = 'XML::LibXML'->load_xml( string => <<'__XML__'); <root> <node a="a b" b="A B" c="AA BB"/> <node a="1" b="2" c="3"/> <node a="X Y Z" b="x y z" c="xx yy zz"/> </root> __XML__ my %complete; for my $node ($xml->documentElement->findnodes('*')) { my ($a, $b, $c) = map $node->getAttribute($_), 'a', 'b', 'c'; if (3 == grep defined, $a, $b, $c) { my @arr_a = split (/ /, $a); my @arr_b = split (/ /, $b); my @arr_c = split (/ /, $c); @complete{@arr_a} = map [ shift @arr_b, shift @arr_c ], @arr_a +; } else { print "Warning! \n"; } } print Dumper \%complete;

    Update: Note that I populate the hash only if all the attributes are defined. In your case, the @arr_X arrays were global, so the hash was repopulated again with the old values. (I use strict and warnings, why don't you?)

    The map expression might look a bit complex for an untrained eye. It just picks one element from b and c for each element of a.

    لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      Thank you a lot ! Your solution helped me to solve this Problem. Now I understand, why it never worked for me. Also thank your for showing me the right way to work further. Best regards!
Re: Multidimensional Hash losts entrys
by cdarke (Prior) on Aug 13, 2014 at 13:22 UTC
    %complete =( @arr_a=>[@arr_b, @arr_c], );
    this is reassigning the hash each time. Anyway, do you really want an array to be the key? Try:
    $complete{$a} = [@arr_b, @arr_c];

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1097274]
Front-paged by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (8)
As of 2020-08-06 12:56 GMT
Find Nodes?
    Voting Booth?
    Which rocket would you take to Mars?

    Results (39 votes). Check out past polls.