aartist has asked for the wisdom of the Perl Monks concerning the following question:

I have a data structure which I like to transform to another one. Is there a Perl Module supporting this or similar transformations?

From:

my $var = [ { 'city' => 'New York', 'name' => 'Bill' }, { 'city' => 'New York', 'name' => 'Ronald' }, { 'city' => 'Boston', 'name' => 'George' } ];
To,
$VAR1 = { 'New York' => [ 'Bill', 'Ronald' ], 'Boston' => [ 'George' ] };
My attempt:
map { push @{$var1->{$_->{city}}}, $_->{name} } @{$var};
Thanks.

Replies are listed 'Best First'.
Re: Data Structure Transformation
by wind (Priest) on Jan 31, 2011 at 20:07 UTC
    Just don't use map, use foreach instead:
    use Data::Dumper; use strict; my $var = [ { 'city' => 'New York', 'name' => 'Bill' }, { 'city' => 'New York', 'name' => 'Ronald' }, { 'city' => 'Boston', 'name' => 'George' } ]; my %result; push @{$result{$_->{city}}}, $_->{name} foreach (@$var); print Dumper(\%result);
    - Miller
Re: Data Structure Transformation
by GrandFather (Saint) on Jan 31, 2011 at 20:32 UTC

    How would a module make the transformation much easier? What would you expect a call to the transform function provided by such a module to look like?

    As an aside, using map in void context is frowned on. It is generally considered clearer to use a for statement modifier:

    push @{$var1->{$_->{city}}}, $_->{name} for @$var;
    True laziness is hard work
      Thanks for the 'map' advice.
      I like to provide same functionality in Template ( TT2). I do not see an easy way. A module plugin would help. I
Re: Data Structure Transformation
by ELISHEVA (Prior) on Jan 31, 2011 at 21:17 UTC

    I imagine there is some module out there that does it, but writing a general purpose routine to convert an array of key-value pairs into a hash of arrays (HoA) is less than 10 lines of code:

    use strict; use warnings; sub convertKeyValueArrayToHash { my ($aData, $sKeyName, $sValueName) = @_; my $hData={}; foreach (@$aData) { my $k = $_->{$sKeyName}; my $v = $_->{$sValueName}; push @{$hData->{$k}}, $v; } return $hData; }

    And a working demo:

Re: Data Structure Transformation
by roboticus (Chancellor) on Feb 01, 2011 at 00:03 UTC

    aartist:

    As I see it, a module would have to give you a way to specify what you're expecting, what you want, and what mapping you want. I don't see how doing that in a general purpose way is going to be any shorter than the perl code that just does the task. Also, if you do anything other than straight mapping (i.e., computations, etc.) then you're making the interface for a data structure transformation module even more complex. I'm quite willing to be proven wrong, but I don't think I am.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: Data Structure Transformation
by planetscape (Chancellor) on Feb 01, 2011 at 11:40 UTC