From: Vishal G on
Hi Guys,

I have a little complicated problem...

I have two arrays

@a = ( ['id', 'name', 'age'],
['1', 'Fred', '24'],
['2', 'Frank', '42'],
);

@b = ( ['id', 'sex'],
['1', 'm' ],
['2', 'm'],
);

I want to join these two AoA, based on id, so the resulting array will
look like this

@c = ( ['id', 'name', 'age', 'sex'],
['1', 'Fred', '24', 'm' ],
['2', 'Frank', '42', 'm'],
);

Any Ideas?

Thanks in advance.
From: Ben Bullock on
On Apr 22, 3:35 pm, Vishal G <v3gu...(a)gmail.com> wrote:
> Hi Guys,
>
> I have a little complicated problem...
>
> I have two arrays
>
> @a = ( ['id', 'name', 'age'],
> ['1', 'Fred', '24'],
> ['2', 'Frank', '42'],
> );
>
> @b = ( ['id', 'sex'],
> ['1', 'm' ],
> ['2', 'm'],
> );
>
> I want to join these two AoA, based on id, so the resulting array will
> look like this
>
> @c = ( ['id', 'name', 'age', 'sex'],
> ['1', 'Fred', '24', 'm' ],
> ['2', 'Frank', '42', 'm'],
> );
>
> Any Ideas?

my %akeys;
@akeys{map $$_[0],@a} = @a;
my %bkeys;
@bkeys{map $$_[0],@b} = @b;
my @c;
for (sort keys %akeys) {
if ($bkeys{$_}) {
push @c, [@{$akeys{$_}},@{$bkeys{$_}}[1..$#{$bkeys{$_}}]];
}
}
for (@c) {
print "[",join (", ",@$_),"]\n";
}
From: Matija Papec on
Vishal G wrote:
> I have a little complicated problem...
>
> I have two arrays
>
> @a = ( ['id', 'name', 'age'],
> ['1', 'Fred', '24'],
> ['2', 'Frank', '42'],
> );
>
> @b = ( ['id', 'sex'],
> ['1', 'm' ],
> ['2', 'm'],
> );
>
> I want to join these two AoA, based on id, so the resulting array will
> look like this
>
> @c = ( ['id', 'name', 'age', 'sex'],
> ['1', 'Fred', '24', 'm' ],
> ['2', 'Frank', '42', 'm'],
> );

Assuming that both @a and @b have same size and same id order,

for my $i (0 .. $#a) {
my $at = $a[$i];
my $bt = $b[$i];
push @$at, @$bt[1 .. $#$bt];
}
use Data::Dumper;
print Dumper \@a;
From: Hartmut Camphausen on
In <<7d3db66d-5cef-4eaa-8cd3-54e489ae1721(a)a5g2000prg.googlegroups.com>>
schrieb Ben Bullock...

> [...]
> my @c;
> for (sort keys %akeys) {
> [...]
> }
> for (@c) {
> print "[",join (", ",@$_),"]\n";
> }

Prints [1, Fred, 24, m]
[2, Frank, 42, m]
[id, name, age, sex]

Take care of the 'sort' ;-)


Alternatively, if you want to take care of the IDs of /both/ arrays,
you could write:


#!perl.exe -w # well, on Windows...
use strict; # always 'use' this one!

my @a = ( ['id', 'name', 'age' ], # just our data...
['2', 'Frank', '42' ],
['1', 'Fred', '24' ],
['3', 'Pat', '36' ],
);
my @b = ( ['id', 'sex' ], # ...to deal with
['1', 'm' ],
['2', 'm' ],
['4', '??' ],
);

my @afields = @{ shift @a }; # get rid of field names,
my @bfields = @{ shift @b }; shift @bfields; # keeping them at hand
my %a = map {$_->[0], $_} @a; # now we can refer to the...
my %b = map {shift @{$_}, $_} @b; # ...data by their IDs

my %seen; # just to avoid duplicates
my @c = ( [ @afields, @bfields ], # field names come first
map { [ $a{$_} ? @{$a{$_}} : ($_, ('') x $#afields),
$b{$_} ? @{$b{$_}} : ( ('') x @bfields )
]
} sort grep { $seen{$_}++ ? 0 : $_ }
keys (%a), keys (%b)
);


....gives

['id', 'name', 'age', 'sex']
['1', 'Fred', '24', 'm' ]
['2', 'Frank', '42', 'm' ]
['3', 'Pat', '36', '' ]
['4', '', '', '??' ]



mfg, Hartmut


--
------------------------------------------------
Hartmut Camphausen h.camp[bei]textix[punkt]de
From: nolo contendere on
On Apr 22, 2:35 am, Vishal G <v3gu...(a)gmail.com> wrote:
> Hi Guys,
>
> I have a little complicated problem...
>
> I have two arrays
>
> @a = ( ['id', 'name', 'age'],
>            ['1', 'Fred', '24'],
>            ['2', 'Frank', '42'],
>          );
>
> @b = ( ['id', 'sex'],
>            ['1', 'm' ],
>            ['2', 'm'],
>          );
>
> I want to join these two AoA, based on id, so the resulting array will
> look like this
>
> @c = ( ['id', 'name', 'age', 'sex'],
>            ['1', 'Fred', '24', 'm' ],
>            ['2', 'Frank', '42', 'm'],
>          );
>
> Any Ideas?

I'm not sure how much control you have over the structure of the data,
but it seems to me that you would be better served if the data were
stored in hashes to begin with:

use strict; use warnings;
use Data::Dumper;

my %people = (
1 => { name => 'Fred', age => 24 },
2 => { name => 'Frank', age => 42 },
);

my %gender = (
1 => { sex => 'm' },
2 => { sex => 'm' },
);

...then it's a simple matter to combine the two structures, keyed by
the id.

for my $id ( keys %people ) {
$people{$id}{sex} = $gender{$id}{sex};
}



print Dumper( \%people ), "\n";