Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Assign a hash to an array

by ravi45722 (Pilgrim)
on Jun 27, 2016 at 09:05 UTC ( [id://1166638]=perlquestion: print w/replies, xml ) Need Help??

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

Here I am assigning(push) a hash to an array of hashes. But when I print hash Its perfect. But when I push that into an array its changing. Here is my code. I also tried with escape('\') character.

$string = "column08=Submit & column10=Delivered & column09=Something" my @matches = grep defined, split / ([|&]) /, $string; $i = 1; foreach my $one (@matches) { if (($one =~ tr/=//) == 1) { my ($key,$value)=(split /=/,$one); %hash = (); $hash{'term'}{$key} = $value; push (@return_array,%hash); } else { push (@symbol_array,$one); } } print Dumper \%hash; print Dumper \@return_array;

Expected Output:

$VAR1 = [ 'term'=> { 'column08' => 'Submit' }, 'term'=> { 'column10' => 'Delivered' }, 'term'=> { 'column09' => 'Something' } ];
Thanks in Advance

Replies are listed 'Best First'.
Re: Assign a hash to an array
by choroba (Cardinal) on Jun 27, 2016 at 09:25 UTC
    You probably want to push a hash reference to the array, not an array - it pushes a list of alternating keys and values. In order to make it work, you should also use a different reference for each iteration:

    my %hash; $hash{term}{$key} = $value; push @return_array, \%hash;

    or, more shortly

    push @return_array, { term => { $key => $value} };

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

      The second one is working very fine. Tq. But when I uses the first one its overwriting

      Output for push @return_array, \%hash;

      $VAR1 = [ { 'term' => { 'column09' => 'Something' } }, $VAR1->[0], $VAR1->[0] ]; $VAR1 = '{"must":[{"term":{"column09":"Something"}},{"term":{"column09 +":"Something"}},{"term":{"column09":"Something"}}]}';

      Output for push @return_array, { term => { $key => $value} };

      $VAR1 = [ { 'term' => { 'column08' => 'Submit' } }, { 'term' => { 'column10' => 'Delivered' } }, { 'term' => { 'column09' => 'Something' } } ]; $VAR1 = '{"must":[{"term":{"column08":"Submit"}},{"term":{"column10":" +Delivered"}},{"term":{"column09":"Something"}}]}';

        Understanding the unexpected result you're getting will really help you in the future.

        use strict; my (%hash,@array); $hash{A}='B'; push @array,\%hash;

        I have pushed into my array a hash reference. If I run this in the debugger, I can see the following:

        x @array 0 HASH(0x300331c4) 'A' => 'B'

        Resuming:

        $hash{B}='C'; push @array, \%hash;

        But:

        x @array 0 HASH(0x300331c4) 'A' => 'C' 1 HASH(0x300331c4) -> REUSED_ADDRESS

        I thought I pushed a different value into the array. I expect two hashes in my array, one with value B and one with C. But that's not what I get. A reference is not a copy of the variable, but a link to that variable. My array contains two references to the same variable, %hash. The first array element reflects the new value in %hash, 'C', and the second just says 'ditto'.

        use strict; my (%hash,@array); $hash{A}='B'; push @array, \%hash; my (%hash); $hash{A}='C'; push @array, \%hash;

        Debugger shows:

        x @array 0 HASH(0x30033194) 'A' => 'B' 1 HASH(0x3015f4e0) 'A' => 'C'

        This time, I created a new hash variable, so the array contains two distinct references. The first array element is unchanged by my actions.

        In this example, it appears I have lost that first %hash by reusing the name. In fact, I can no longer retrieve its values using that name. But the value is preserved by the reference in the array.

        Minor update made for clarity.

        But God demonstrates His own love toward us, in that while we were yet sinners, Christ died for us. Romans 5:8 (NASB)

        Are you sure you included the my %hash line, too?

        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: Assign a hash to an array
by hippo (Bishop) on Jun 27, 2016 at 09:25 UTC
    But when I push that into an array its changing.

    To keep the structure, push the reference, not the hash:

    push (@return_array, \%hash);

    If that doesn't give you what you want then you'll have to be a lot more specific about what you do want. (Note: ravi45722 has since silently updated his post to include the output that he wants)

Re: Assign a hash to an array
by haukex (Archbishop) on Jun 27, 2016 at 09:42 UTC

    Hi ravi45722,

    I was just about to post asking what you want your output to look like, but you just edited your post to add the expected output. Have a look at How do I change/delete my post?, especially "It is uncool to update a node in a way that renders replies confusing or meaningless".

    In addition to what others have said about your creation of the data structure, regarding your expected output: Interestingly, your code does produce the output you expect:

    $VAR1 = [ 'term', { 'column08' => 'Submit' }, 'term', { 'column10' => 'Delivered' }, 'term', { 'column09' => 'Something' } ];

    This is equivalent to your expected output, which uses the arrow operator (aka "fat comma") after 'term'. But because @return_array is an array and not a hash, I'm pretty sure you'll never get Data::Dumper to output the fat comma between some of its elements. Are you confusing an array and a hash? Maybe you could show how you later want to look things up in @return_array? Also you'll probably want to review perlreftut and perldsc in detail.

    Hope this helps,
    -- Hauke D

Re: Assign a hash to an array (ref)
by Anonymous Monk on Jun 27, 2016 at 09:42 UTC
    These are the same
    push @foo , 1,2,3; push @foo, @bar; push @foo, %baz;

    but different from these , which are the same

    push @foo , { 1,2,3 }; push @foo, \%baz;

    and different from this one , which is similar to the last two

    push @foo, \@bar;

    Do you get it? You push references, otherwise its just a list

Re: Assign a hash to an array
by $h4X4_|=73}{ (Monk) on Jun 27, 2016 at 09:33 UTC

    You are clearing the hash and not the array also.

    use warnings; use strict; use Data::Dumper; my $string = "column08=Submit & column10=Delivered & column09=Somethin +g"; my @matches = grep defined, split / ([|&]) /, $string; my %hash = (); my @return_array = (); my @symbol_array = (); # dead code foreach my $one (@matches) { if (($one =~ tr/=//) == 1) { my ($key,$value)=(split /=/,$one); %hash = (); @return_array = (); # clear the array also $hash{'term'}{$key} = $value; push (@return_array,%hash); } else # dead code { push (@symbol_array,$one); } } print Dumper \%hash; print Dumper \@return_array;

    ...

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1166638]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (4)
As of 2024-04-25 10:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found