Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

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 scrutinizing the Monastery: (5)
As of 2020-07-05 20:58 GMT
Find Nodes?
    Voting Booth?

    No recent polls found