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

I have a program that takes an array created in a loop and pushes it into an AoA. When I have all my arrays I look for a Intersection on them to find common elements in all Arrays. There can be almost infinite arrays.

How do I get my @comp data structure into the &intersection subroutine?

@comp can hold up to N arrays, so I'd like to pass the entire data structure in at once and output an array of all the Intersection elements into one CSV string.

I'm really confused on how to do it.
#!/usr/bin/perl -w use strict; my @array1 = qw{ bob larry melon fruit}; my @array2 = qw{ bob larry melon apple}; my array3 = qw{ bob larry fruit apple}; my @comp; push @comp, [@array1]; push @comp, [@array2]; push @comp, [@array3]; ############# # # I'm not sure what to do here to make the @comp AoA compatable with +the &intersection subroutine # ############ my $newIntersection = &intersection( \%array1, \%wisconsin, \%rockford + ); print join(" ", keys %{ $newIntersection }), "\n"; sub intersection { my ( $i, $sizei ) = ( 0, scalar keys %{ $_[0] }); my ( $j, $sizej ); for ( $j = 1; $j < @_; $j++ ) { $sizej = keys %{ $_[ $j ] }; ( $i, $sizei ) = ( $j, $sizej ) if $sizej < $sizei; } my @intersection = keys %{ splice @_, $i, 1 }; my $set; while ( $set = shift ) { @intersection = grep { exists $set->{ $_ } } @intersectio +n; } my %intersection; @intersection{ @intersection } = (); return \%intersection; }
What would be the reccomended process to get a data structure of Arrays into the sub?
  • Comment on How to change this AoA to be compatable with an Intersection Subroutine?
  • Download Code

Replies are listed 'Best First'.
Re: How to change this AoA to be compatable with an Intersection Subroutine?
by xdg (Monsignor) on Feb 02, 2006 at 23:17 UTC

    It looks like intersection takes as its argument an AoH (array of references to hashes):

    intersection( \%array1, \%wisconsin, \%rockford )

    What you have is an AoA, so you need to convert your AoH to an AoH -- or just make one in the first place. Here's one way, assuming that the "value" for each entry in the hash doesn't matter (here set to 1):

    push @comp, { map { $_ => 1 } @array1 };

    That said, your code winds up a bit wooley, creating arrays, then hashes and so on, just to get an intersection hash from which you have to extract the keys to get your intersection list.

    Instead, you might want to use a nice module like List::Compare that lets you just work with an AoA and gives you back an array:

    use strict; use List::Compare; my @array1 = qw{ bob larry melon fruit}; my @array2 = qw{ bob larry melon apple}; my array3 = qw{ bob larry fruit apple}; my @comp; push @comp, [@array1]; push @comp, [@array2]; push @comp, [@array3]; my $lc = List::Compare->new( @comp ); my @intersection = $lc->get_intersection;

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.