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
| [reply] [d/l] [select] |
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.
| [reply] [d/l] |
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;
| [reply] [d/l] |
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.
| [reply] |