in reply to Hash of Hash Redux

Perhaps your array @populations should be a scalar count of however many populations you wish to generate. In your subroutine you can just create your category arrays once and interpolate them into new anonymous arrays for each population. If you take a reference to them as suggested by moritz then each population will have the same individual, chromosome1 and chromosome2 arrays.

use strict; use warnings; use Data::Dumper; my %HoH; my $popCt = 4; gener(); print Data::Dumper->Dumpxs([\%HoH], [q{*HoH}]); sub gener { my @chroma = ( 0...10 ); my @chromb = ( 0...10 ); my @ind = ( 0...10 ); for my $pop ( 1 .. $popCt ) { $HoH{$pop} = { individual => [ @ind ], chromasome1 => [ @chroma ], chromasome2 => [ @chromb ], }; } }

This produces

%HoH = ( '4' => { 'chromasome2' => [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], 'chromasome1' => [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], 'individual' => [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] }, '1' => { 'chromasome2' => [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], 'chromasome1' => [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], 'individual' => [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] }, '3' => { 'chromasome2' => [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], 'chromasome1' => [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], 'individual' => [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] }, '2' => { 'chromasome2' => [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], 'chromasome1' => [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], 'individual' => [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] } );

I hope this is of use.

Cheers,

JohnGG

Replies are listed 'Best First'.
Re^2: Hash of Hash Redux
by BioNrd (Monk) on Oct 31, 2007 at 18:24 UTC
    That works like a charm. Thanks very much for the help!

    I have another thing...of course...the life of a noobie

    I want to now make @ind, @chroma @chromb interactive for each population

    Again this should work, but I am lost again. The @chroma, @chromb, @ind will then go into the hash maker that you all got working for me

    Also you all can yell at me all you want about use strict...no perl books have told me how to do that! I am flying without a net! Any good references?

      I am not sure what you are trying to do in terms of the algorithm but there are a few problems with your code.

      Firstly, you do push(my @chroma, $genea); and push(my @chromb, $geneb); inside the scope of the while ($ranpop) { ... } loop. That means that each time around the loop you create new lexically scoped arrays to push data onto and by the time you get to the return they are out of scope so inaccessible.

      Secondly, I'm not sure what you are doing with the

      my $center = 1; ... while ($center--) { ... return ... ; }

      That loop is meaningless as it stands because it is going to terminate early with the return and would only run the once anyway. If your $center is more than 1 it will still do the same thing as the return will always leave the subroutine. Perhaps the return should me moved to after the loop.

      Thirdly, if you want to return more than one array (or hashes for that matter) from a subroutine you must return them by reference because from the caller's point of view, the three arrays you return come back as one big list. Do it something like this.

      sub makeArrays { my @arrA = ( 1 .. 6 ); my @arrB = qw{ fred joe bill pete }; my @arrC = ( 1, 3, q{abc}, 8 ); return \@arrA, \@arrB, \@arrC; } my ( $refToArrA, $refToArrB, $refToArrC ) = makeArrays(); my @newArrA = @$refToArrA; my $elemTwoOfArrB = $refToArrB->[2];

      I hope this is of use.

      Cheers,

      JohnGG

        Yes it was of pleanty of use. But tell me, am I trying to do the impossible? Here is where I am right now...without the help my comp would go out the window
        use warnings; use strict; use Data::Dumper; my $popCt = 4; my %HoH; for (1 .. $popCt) { my ( $refToArrA, $refToArrB, $refToArrC ) = makeArrays(); &gener(); } print Data::Dumper->Dumpxs([\%HoH], [q{*HoH}]); sub makeArrays { my ($upper, $lower); print 'Enter lower bound: '; chomp ($lower = <STDIN>); print 'Enter upper bound: '; chomp ($upper = <STDIN>); my @chroma; my @chromb; my $ranpop; $ranpop = int rand($upper - $lower + 1) + $lower; print $ranpop . "\n"; my @arrA = ( 1 .. $ranpop ); my $limiter = 50; my @holda; my @holdb; while ($ranpop) { my $genea = int rand ($limiter); push(@holda, $genea); my $geneb = int rand ($limiter); push(@holdb, $geneb); $ranpop--; } my @arrB = ( @holda ); my @arrC = ( @holdb ); return \@arrA, \@arrB, \@arrC; } sub gener { my @newind = @$refToArrA; my @newchroma = @$refToArrB; my @newchromb = @$refToArrC; for my $pop ( 1 .. $popCt ) { $HoH{$pop} = { individual => [ @newind ], chromasome1 => [ @newchroma ], chromasome2 => [ @newchromb ], }; } }
        In an ideal world I would have 4 populations with 4 different sets of individuals with 4 different sets of chromosome A and B's. At this point I feel like I am going about this all wrong...

        I know strict and warnings are returing things...but I don't know what they mean, google only helps so much.

        I really appreciate the help, but tell me if I ask the impossible.

      Strictures (strict and warnings) turn on various extra checking for dubious practices or programming errors. use strict requires (among many other things) that variables are declared (using my) and that various techniques that often cause confusion or have been made redundant in newer versions of Perl are not used.

      use warnings makes various run time checks. The most important one is that variables have been initialized before their contents are used. Together these two strictures provide an extremely useful early warning system for many common coding mistakes. Always use strictures in Perl. ;)


      Perl is environmentally friendly - it saves trees