[Chicago-talk] Combine like hash elements
Joel Limardo
joel.limardo at forwardphase.com
Mon Nov 23 13:46:21 PST 2015
I disagree that this should be put in a database unless you have sufficient
values to warrant that. If you are dealing with just a few dozen values
relying upon a database to essentially sort a hash is not very Perl-ish I
think. At any rate, here is a more verbose example that uses Data::Dumper.
The other examples provided before should be better, but I offer this
because you can debug it and see what is happening line by line:
use strict;
use Data::Dumper;
my $targetRef;
my $hashRef =
{
'11' => {'AMOUNT' => '20.00','ID' => '11','NAME' => 'Lincoln Park'},
'12' => {'AMOUNT' => '38.00','ID' => '12','NAME' => 'Bucktown'},
'13' => {'AMOUNT' => '41.00','ID' => '11','NAME' => 'Lincoln Park'}
}; #ID on line 3 fixed to match first line id
foreach my $structId(keys %$hashRef)
{
my $struct = $hashRef->{$structId};
if (!$targetRef->{$struct->{'ID'}}){
$targetRef->{$struct->{'ID'}} = { 'NAME' => $struct->{'NAME'},
'ID' => $struct->{'ID'},
'AMOUNT'=> $struct->{'AMOUNT'}
};
} else {
$targetRef->{$struct->{'ID'}}->{'AMOUNT'} +=
$struct->{'AMOUNT'};
}
}
print Dumper $targetRef;
1;
== produces ==
$VAR1 = {
'12' => {
'ID' => '12',
'AMOUNT' => '38.00',
'NAME' => 'Bucktown'
},
'11' => {
'NAME' => 'Lincoln Park',
'AMOUNT' => '61',
'ID' => '11'
}
};
On Mon, Nov 23, 2015 at 12:55 PM, imran javaid <imranjj at gmail.com> wrote:
> You could also push the aggregation to the DB server and have it do the
> sum by name.
>
> On Mon, Nov 23, 2015 at 12:52 PM, <richard at rushlogistics.com> wrote:
>
>> Hello Everybody,
>>
>>
>>
>> Thank you for all the replies. The ID field did not need to be preserved.
>> However, I was having difficulty conceptualizing the manipulation of the
>> hash so I decided to use DBI->bind_colums instead and iterate throught the
>> values in a way that I found at least a bit more clear. Still working on
>> cleaning this up but this is at least the direction that I am going in.
>>
>>
>>
>> Thanks again for the help.
>>
>>
>>
>> my ($DID, $AMOUNT, $NAME,);
>> $sth->bind_columns(\($DID, $AMOUNT, $NAME));
>>
>> my $lastN;
>> my $lastA;
>> my @CAMS;
>> my $keepN;
>> my $keepA;
>>
>> while ($sth->fetch) {
>>
>> if ($lastN) {
>>
>> if ($NAME eq $lastN) {
>>
>> #print "Combine $AMOUNT, $NAME\n";
>> $keepA = $AMOUNT + $lastA;
>> $keepN = $NAME;
>>
>> } else {
>>
>> $keepA = $AMOUNT;
>> $keepN = $NAME;
>>
>> }
>>
>> }
>>
>> # print "$DID, $AMOUNT, $NAME\n";
>>
>> $lastN = $NAME;
>> $lastA = $AMOUNT;
>>
>> push(@CAMS, $keepA . " " . $keepN);
>>
>>
>> }
>>
>>
>> On Mon, 23 Nov 2015 11:28:40 -0600, Steven Lembark <lembark at wrkhors.com>
>> wrote:
>>
>> On Mon, 23 Nov 2015 10:10:41 -0600
>> richard at rushlogistics.com wrote:
>>
>> > I have a hash reference with the following structure:
>> >
>> > {
>> > '11' => {'AMOUNT' => '20.00','ID' => '11','NAME' => 'Lincoln Park'},
>> > '12' => {'AMOUNT' => '38.00','ID' => '12','NAME' => 'Bucktown'},
>> > '13' => {'AMOUNT' => '41.00','ID' => '12','NAME' => 'Lincoln Park'}
>> > }
>> >
>> > Can anyone tell me how I can combine them by 'NAME' so that I would
>> have:
>> >
>> > {
>> > '11' => {'AMOUNT' => '61.00','ID' => '11','NAME' => 'Lincoln Park'},
>> > '12' => {'AMOUNT' => '38.00','ID' => '12','NAME' => 'Bucktown'},
>> > }
>>
>> You don't seem to care about the keys (loosing key "13" wasn't
>> a problem).
>>
>> Q: Are the ID values important or could they be discarded?
>>
>> If so then just make a new hash keyed by NAME and accumulate
>> the AMOUNT values:
>>
>> my %resultz = ();
>>
>> for( values %inputz )
>> {
>> my ( $name, $amt, $id ) = @{ $_ }{ qw( NAME AMOUNT ID ) };
>> my $val
>> = $resultz{ $name } ||= { ID => $id, NAME => $name };
>>
>> $val->{ AMOUNT } += $amt;
>> }
>>
>> # at this point %resultz is keyed by name with an id and amount
>> # for each entry.
>>
>> %inputz = ();
>>
>> while( my ( $name, $val ) = each %resultz )
>> {
>> $inputz{ $val->{ ID } } = $val;
>> }
>>
>> # at this point the original inputs hash is keyed by ID
>> # with values having a name, accumulated amount, and id.
>> # multiple id's are collapsed into a single ID with the
>> # value of the first record for that name.
>>
>> --
>> Steven Lembark 3646 Flora Pl
>> Workhorse Computing St Louis, MO 63110
>> lembark at wrkhors.com +1 888 359 3508
>> _______________________________________________
>> Chicago-talk mailing list
>> Chicago-talk at pm.org
>> http://mail.pm.org/mailman/listinfo/chicago-talk
>>
>>
>>
>>
>> _______________________________________________
>> Chicago-talk mailing list
>> Chicago-talk at pm.org
>> http://mail.pm.org/mailman/listinfo/chicago-talk
>>
>
>
> _______________________________________________
> Chicago-talk mailing list
> Chicago-talk at pm.org
> http://mail.pm.org/mailman/listinfo/chicago-talk
>
--
Sincerely,
Joel Limardo
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.pm.org/pipermail/chicago-talk/attachments/20151123/173202dc/attachment.html>
More information about the Chicago-talk
mailing list