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;