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

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

  • Comment on Re: How to merge two arrays within the hash of arrays based on unique name.

Replies are listed 'Best First'.
Re^2: How to merge two arrays within the hash of arrays based on unique name.
by LanX (Saint) on Jul 14, 2020 at 09:51 UTC
    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.

        I simplified the code and added comments. HTH!

        use strict; use warnings; use Data::Dump qw/pp dd/; # --- input data 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', } ); # --- join elements into temporary hash by name my %tmp_hash; my $order = 0; for my $record (@sorted_data) { my $name = $record->{name}; # create new hash only if $name unknown $tmp_hash{$name} //= { name => $name, _order => $order++, # preserve original order }; # concat other elements for (qw/count_banking count_payment/) { $tmp_hash{$name}{$_} .= $record->{$_}; } } # --- copy hash values by order my @new_sorted_data = sort { $a->{_order} <=> $b->{_order} } values %tmp_hash; # --- discard temporary _order element delete $_->{_order} for @new_sorted_data; # --- dump result pp \@new_sorted_data;

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

      Thank you so much Rolf.
Re^2: How to merge two arrays within the hash of arrays based on unique name.
by Sami_R (Sexton) on Jul 14, 2020 at 09:28 UTC

    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.