Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

How to merge two arrays within the hash of arrays based on unique name.

by Sami_R (Sexton)
on Jul 14, 2020 at 01:49 UTC ( #11119279=perlquestion: print w/replies, xml ) Need Help??

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

Hi PerlMonks, Good Morning

Have a list of array hash, which printed below.

$logger->log( "sorted_data = ".Dumper(@sorted_data)); sorted_data = $VAR1 = { 'count_payment' => '', 'count_banking' => '31 (62.00)', 'name' => 'Parking Eye [LTD] One', }; $VAR2 = { 'count_payment' => '10 (144.00)', 'count_banking' => '', 'name' => 'Parking Eye [LTD] Two', }; $VAR3 = { 'count_payment' => '2 (80.42)', 'count_banking' => '', 'name' => 'Parking Eye [LTD] Three', }; $VAR4 = { 'count_payment' => '', 'count_banking' => '4 (982.00)', 'name' => 'Parking Eye [LTD] Two', };

Please, I need to merge two arrays with in the hash array based on the unique name condition, if ($a->{name} <=> $b->{name}). then move 'count_banking' => '4 (982.00)' value to the second where 'count_banking' => '' and remove the last array.

Expected output:

sorted_data = $VAR1 = { 'count_payment' => '', 'count_banking' => '31 (62.00)', 'name' => 'Parking Eye [LTD] One', }; $VAR2 = { 'count_payment' => '10 (144.00)', 'count_banking' => '4 (982.00)', 'name' => 'Parking Eye [LTD] Two', }; $VAR3 = { 'count_payment' => '2 (80.42)', 'count_banking' => '', 'name' => 'Parking Eye [LTD] Three', };

I tried like this below and stuck... please give me direction to achieve as expected output. Apologise if I showed here wrong approach.

foreach my $row ( sort { $a->{name} <=> $b->{name} } @sorted_data ) +{ #Move the values to second and remove the last one }

Thanks in advance.

Replies are listed 'Best First'.
Re: How to merge two arrays within the hash of arrays based on unique name.
by jcb (Parson) on Jul 14, 2020 at 02:23 UTC

    Try building a hash of hashes, keyed by $_->{name} and updating $Hash{$_->{name}}->{count_banking} as you go if the target hash element already exists. See perldsc for more.

    Also note that your question describes an array of hashes, not a hash of arrays.

      Hi JCB, Apologies for mentioning hash of arrays instead of array of hashes, thanks for the document referred which helps me understand better.

Re: How to merge two arrays within the hash of arrays based on unique name.
by LanX (Cardinal) on Jul 14, 2020 at 08:01 UTC
    You want to merge hashes with the same "name" key.

    But it's not clear how other keys are supposed to merge, in your example is one value always blank.

    Is this guaranteed? What if not?

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      Just joining ...

      use strict; use warnings; use Data::Dump qw/pp dd/; my @sorted_data = ( { 'count_payment' => '', 'count_banking' => '31 (62.00)', 'name' => 'Parking Eye [LTD] One', }, { 'count_payment' => '10 (144.00)', 'count_banking' => '', 'name' => 'Parking Eye [LTD] Two', }, { 'count_payment' => '2 (80.42)', 'count_banking' => '', 'name' => 'Parking Eye [LTD] Three', }, { 'count_payment' => '', 'count_banking' => '4 (982.00)', 'name' => 'Parking Eye [LTD] Two', } ); my %tmp; my $order = 0; for my $record (@sorted_data) { my $target = \ $tmp{$record->{name}}; $$target->{name} = $record->{name}; $$target->{_order} //= $order++; for (qw/count_banking count_payment/){ $$target->{$_} .= $record->{$_}; } } my @new_sorted_data = sort { $a->{_order} <=> $b->{_order} } values %tmp; delete $_->{_order} for @new_sorted_data; pp \@new_sorted_data;

      -*- mode: compilation; default-directory: "d:/exp/" -*- Compilation started at Tue Jul 14 11:51:06 C:/Perl_524/bin\perl.exe -w d:/exp/pm_hash_join.pl [ { count_banking => "31 (62.00)", count_payment => "", name => "Parking Eye [LTD] One", }, { count_banking => "4 (982.00)", count_payment => "10 (144.00)", name => "Parking Eye [LTD] Two", }, { count_banking => "", count_payment => "2 (80.42)", name => "Parking Eye [LTD] Three", }, ] Compilation finished at Tue Jul 14 11:51:07

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        Hi Rolf, your code works charm, thank you so much. Finding difficult to understand the code, please add the comment especially for the copied code lines below, would be very helpful.

        my $target = \ $tmp{$record->{name}}; $$target->{name} = $record->{name}; $$target->{_order} //= $order++; delete $_->{_order} for @new_sorted_data;

        Thanks again.

        Thank you so much Rolf.

      Hi Rolf,

      Yes please, want to merge hashes with the same 'name' key. For sure, One or the other value is always blank. for example: in this case if 'count_payment' => '10 (144.00)' has value then on the other 'count_payment' => '' would be blank AND if 'count_banking' => '' has blank then on the other 'count_banking' => '4 (982.00)' has value.

      Many Thanks.

Re: How to merge two arrays within the hash of arrays based on unique name.
by tybalt89 (Prior) on Jul 18, 2020 at 13:39 UTC
    #!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11119433 use warnings; my @before = ( { 'count_payment' => '', 'count_banking' => '31 (62.00)', 'name' => 'Parking Eye [LTD] One', }, { 'count_payment' => '10 (144.00)', 'count_banking' => '', 'name' => 'Parking Eye [LTD] Two', }, { 'count_payment' => '2 (80.42)', 'count_banking' => '', 'name' => 'Parking Eye [LTD] Three', }, { 'count_payment' => '', 'count_banking' => '4 (982.00)', 'name' => 'Parking Eye [LTD] Two', } ); my @after; my %names; for my $record ( @before ) { my $hashref = $names{ $record->{name} } //= $after[ @after ] = {}; $hashref->{$_} ||= $record->{$_} for keys %$record; } use Data::Dump 'dd'; dd \@after;

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://11119279]
Approved by jcb
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 2021-05-15 19:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Perl 7 will be out ...





    Results (150 votes). Check out past polls.

    Notices?