Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Insert into element into arrays ref

by Anonymous Monk
on Aug 22, 2019 at 17:23 UTC ( #11104862=perlquestion: print w/replies, xml ) Need Help??

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

Hi there Monks!

I need to insert the @$data2 value into the @$data1. The code I have only updates the first element in the @$data1:
#!/usr/bin/perl use strict; use warnings; use Data::Dumper; my $data1 = [ { 'NAME' => 'PAUL DY', 'DATE' => '2009-05-05', 'NUMBER' => '00001', }, { 'NAME' => 'ANTHONY RD', 'DATE' => '2012-01-07', 'NUMBER' => '00003', }, { 'NAME' => 'RUTH RD', 'DATE' => '2018-01-07', 'NUMBER' => '00023', }, ]; my $data2 = [ { 'CODE' => 'X11', } ]; @$data1= ({map { %$_ } (@$data1, @$data2)}); print Dumper $data1;

Thanks for helping!

Replies are listed 'Best First'.
Re: Insert into element into arrays ref
by Fletch (Chancellor) on Aug 22, 2019 at 17:27 UTC

    No need to futz around with map. Just push the contents of @{$data2} onto @{$data1}.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

      Using push:

      push @$data1, @$data2;

      Result:
      [ { 'DATE' => '2009-05-05', 'NAME' => 'PAUL DY', 'NUMBER' => '00001' }, { 'NAME' => 'ANTHONY RD', 'NUMBER' => '00003', 'DATE' => '2012-01-07' }, { 'NUMBER' => '00023', 'NAME' => 'RUTH RD', 'DATE' => '2018-01-07' }, { 'CODE' => 'X11' } ]

      Looking for this:
      [ { 'NAME' => 'PAUL DY', 'DATE' => '2009-05-05', 'NUMBER' => '00001', 'CODE' => 'X11', }, { 'NAME' => 'ANTHONY RD', 'DATE' => '2012-01-07', 'NUMBER' => '00003', 'CODE' => 'X11', }, { 'NAME' => 'RUTH RD', 'DATE' => '2018-01-07', 'NUMBER' => '00023', 'CODE' => 'X11', }, ]

      Thanks!

        One way (update: see the Perl Data Structures Cookbook):

        c:\@Work\Perl\monks>perl use strict; use warnings; use Data::Dumper; my $data1 = [ { 'NAME' => 'PAUL DY', 'DATE' => '2009-05-05', 'NUMBER' => '00001', }, { 'NAME' => 'ANTHONY RD', 'DATE' => '2012-01-07', 'NUMBER' => '00003', }, { 'NAME' => 'RUTH RD', 'DATE' => '2018-01-07', 'NUMBER' => '00023', }, ]; my $data2 = [ { 'CODE' => 'X11', } ]; foreach my $hashref (@$data1) { %$hashref = (%$hashref, %{ $data2->[0] }); } print Dumper $data1; __END__ $VAR1 = [ { 'NAME' => 'PAUL DY', 'DATE' => '2009-05-05', 'CODE' => 'X11', 'NUMBER' => '00001' }, { 'NAME' => 'ANTHONY RD', 'DATE' => '2012-01-07', 'CODE' => 'X11', 'NUMBER' => '00003' }, { 'NAME' => 'RUTH RD', 'DATE' => '2018-01-07', 'CODE' => 'X11', 'NUMBER' => '00023' } ];

        Update 1: Note that using this method, if there is a key in the hash referent of the single element of the  $data2 array referent that is the same as one in a hash referent of any  $data1 array referent, the value of the former will silently overwrite the value of the latter. (Update: For instance, see what happens if  $data2 happens to be
            my $data2 = [ { 'CODE' => 'X11',  'NAME' => 'JONES', } ];
        instead. (Update: This exact problem is discussed more clearly in the FAQ referenced by BillKSmith here.))

        Update 2: Here's a testing framework for playing around with other approaches. See Test::More, Test::NoWarnings.


        Give a man a fish:  <%-{-{-{-<

        You are merging the hash in $data2 with each of the hashes in $data1. Read the FAQ.
        perldoc -q "How do I merge two hashes?"
        Bill
Re: Insert into element into arrays ref
by NetWallah (Canon) on Aug 23, 2019 at 00:15 UTC
    Another way - UPDATING the contents of $data1 without replacing them,
    and arguably easier on the eyes:
    while(my($k,$v)=each %{$data2->[0]}){ $_->{$k} = $v for @$data1; }
    UPDATE: Changed "for" to "while" to accomodate multi-key hashref in $data2, per aartist (++).

                    "From there to here, from here to there, funny things are everywhere." -- Dr. Seuss

      for (my($k,$v)=each %{$data2->[0]}){ $_->{$k} = $v for @$data1; }

      That works for a single key/value element in $data2->[0], but given that it can work for only a single element, why not use the ocularly even easier

      my ($k,$v) = %{$data2->[0]}; $_->{$k} = $v for @$data1;

      c:\@Work\Perl\monks>perl use strict; use warnings; use Data::Dumper; my $data1 = [ { 'NAME' => 'PAUL DY', 'DATE' => '2009-05-05', 'NUMBER' => '00001', }, { 'NAME' => 'ANTHONY RD', 'DATE' => '2012-01-07', 'NUMBER' => '00003', }, { 'NAME' => 'RUTH RD', 'DATE' => '2018-01-07', 'NUMBER' => '00023', }, ]; my $data2 = [ { 'CODE' => 'X11', 'X' => 'Y', } ]; for (my($k,$v)=each %{$data2->[0]}){ $_->{$k} = $v for @$data1; } print Dumper $data1; __END__ $VAR1 = [ { 'NAME' => 'PAUL DY', 'X' => 'Y', 'DATE' => '2009-05-05', 'NUMBER' => '00001' }, { 'NAME' => 'ANTHONY RD', 'X' => 'Y', 'DATE' => '2012-01-07', 'NUMBER' => '00003' }, { 'NAME' => 'RUTH RD', 'X' => 'Y', 'DATE' => '2018-01-07', 'NUMBER' => '00023' } ];


      Give a man a fish:  <%-{-{-{-<

        for (my($k,$v)=each %{$data2->[0]}){

        You may need to use while in place of for to get all the value in %{$data2->[0]}

Re: Insert into element into arrays ref
by aartist (Monk) on Aug 23, 2019 at 10:43 UTC
    We need to change the object pointed by each hashref of data1. It accommodates for multiple key/values in data2.
    for my $hash1 (@{$data1}){ for my $hash2 (@{$data2}){ for my $key (keys %$hash2){ $hash1->{$key}=$hash2->{$key}; } } } print Dumper $data1;
      It accommodates for multiple key/values in data2.

      It accommodates multiple hashes in  $data2 with each hash having multiple key/values! This exceeds the implied requirement of the OP, but I find that requirements tend to expand spontaneously in these situations anyway.

      I was a bit daunted by the time-complexity of the triple nesting of your solution. I tried to come up with some alternatives. I think these all work, but neither your solution nor any of mine have been thoroughly tested by me. Unfortunately, I think the big-Os of all these solutions, yours and mine, are going to turn out to be exactly the same!

      foreach my $hashref (@$data1) { %$hashref = (%$hashref, %$_) for @$data2; } for my $hash1 (@$data1) { @{ $hash1 }{ keys %$_ } = values %$_ for @$data2; } foreach my $hash1 (@$data1) { for my $hash2 (@$data2) { map { $hash1->{$_} = $hash2->{$_} } keys %$hash2; } } for my $hash1 (@$data1) { for my $hash2 (@$data2) { while (my ($k2, $v2) = each %$hash2) { $hash1->{$k2} = $v2; } } }


      Give a man a fish:  <%-{-{-{-<

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (5)
As of 2019-09-18 17:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    The room is dark, and your next move is ...












    Results (236 votes). Check out past polls.

    Notices?