Hi monkers,

First post here. I'm using perl professionally for more than a year now but I'm only doing simple tasks. I'm always impressed when I come here because I don't understand half the code I read... and to improve myself I would like to know how you would have done the function posted below.

It's a simple function that I created to do "group by" on rows retrieved by fetchall_arrayref({});

I'm particulary interessed in:

- better style

- performance improvement

- or more black magic ;)

Here my .pl :

#!/usr/bin/perl use strict; use Data::Dumper; my $rows = [ {'Category' => 'Animal', 'Type' => 'Dog', 'Model' => +'Labrador', 'Quantity' => 5}, {'Category' => 'Animal', 'Type' => 'Dog', 'Model' => +'Rottweiler', 'Quantity' => 2}, {'Category' => 'Animal', 'Type' => 'Cat', 'Model' => +'Chartreux', 'Quantity' => 4}, {'Category' => 'Vehicle', 'Type' => 'Car', 'Model' => +'Ford', 'Quantity' => 10}, ]; my $groupedRows = rowsGroupBy($rows, ['Category', 'Type'], { 'SUM' => +['Quantity'] }); print $groupedRows->{'Animal', 'Dog'}->{'Quantity'}; # 7 print "\n"; print Dumper $groupedRows; # $VAR1 = { # 'AnimalCat' => { # 'Type' => 'Cat', # 'Quantity' => 4, # 'Category' => 'Animal' # }, # 'VehicleCar' => { # 'Type' => 'Car', # 'Quantity' => 10, # 'Category' => 'Vehicle' # }, # 'AnimalDog' => { # 'Type' => 'Dog', # 'Quantity' => 7, # 'Category' => 'Animal' # } # }; # $rows: Array of hash_ref (rows) # $groupBy: Array of field to use for the group by. Can be empty if yo +u want to do $options on all rows. # $options: Hash with following option handled: # SUM => @array: Compute the sum. # PILE => @array: Create an array containing all values for + the field. # MAX => @array: The greatest value encountered. # Return hash_ref with group by as keys (list) if group by is not empt +y. # Return hash_ref with $options as keys if group by is empty. sub rowsGroupBy { my($rows, $groupBy, $options) = @_; return undef if @$rows+0 == 0 || !defined($groupBy); my $result = {}; foreach my $row (@$rows) { my $value; my $key = join(chr(28), map { $row->{$_} } @$groupBy); if(exists($result->{$key})) { $value = $result->{$key}; } else { $value = {}; $result->{$key} = $value; } foreach(@$groupBy) { $value->{$_} = $row->{$_}; } foreach(@{$options->{'SUM'}}) { $value->{$_} += $row->{$_}; } foreach(@{$options->{'PILE'}}) { push(@{$value->{$_}}, $row->{$_}); } foreach(@{$options->{'MAX'}}) { $value->{$_} = $row->{$_} if !defined($value->{$_}) || $ro +w->{$_} gt $value->{$_}; } if($options->{'KEEP_UNDERLYING_ROWS'}) { push(@{$value->{'UNDERLYING_ROWS'}}, $row); } } return $result->{''} if @$groupBy == 0; return $result; }

In reply to Improve this "group by" perl sub by seblec

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.