Hi, Doug, :)

On Mon, 11 Nov 2002, Cacialli, Doug wrote:

> I'm new to programming in perl, and relatively new to programming at
> all, so I apologize if this is a little hard to follow.

Wasn't hard at all!  You described the problem very succinctly.

> I've got oodles of data.  It looks like this:

> 0 @F1@ FAM
> 1 HUSB @I13@
> 1 WIFE @I14@
> 1 CHIL @I8@
> 0 @F2@ FAM
> 1 HUSB @I10@
> 1 WIFE @I8@
> 1 CHIL @I11@
> 1 CHIL @I12@

> The first numeric portion (either 0 or 1) is irrelevant, the second
> portion either a family number (@F1@, @F2@, etc.) OR relationship
> (HUSB, WIFE, or CHIL), and the third portion is an ID number (@I13@,
> @I14@, @I8@, etc.).

> What I need to do is create a series of unnamed arrays and reference
> them hash elements.  In other words, I need to do the equivalent to
> this:

> $individuals{"F1"}[0] = "I13";
> $individuals{"F1"}[1] = "I14";
> $individuals{"F1")[2] = "I8";
> $individuals{"F2")[0] = "I10";
> $individuals{"F2")[1] = "I8";
> $individuals{"F2")[2] = "I11";
> $individuals{"F2")[3] = "I12";

Is this what you *really* want to do?  I notice that you lose the
"familial relationship" when you simply push all the members of a
family onto an array.  Don't you care about which of the [0], [1], or
[2] is the HUSB, WIFE, or CHIL? ;)  You could easily keep that data as
well, if you wanted to.

If we do solve it the way you indicate, then you asking to treat the
value for the hash key "F1" (family) as an array reference.  Then you
simply push() all of the family IDs onto the array as you find them.

Here's what I came up with to do this:

#!/usr/bin/perl

use strict;
use warnings;

my $data =
'0 @F1@ FAM
1 HUSB @I13@
1 WIFE @I14@
1 CHIL @I8@
0 @F2@ FAM
1 HUSB @I10@
1 WIFE @I8@
1 CHIL @I11@
1 CHIL @I12@
';

my @lines = split /\n/, $data;

my %individuals = ();

my $curr_fam;
foreach( @lines ) {
   s/@//g;
   my ($placeholder, $relation, $id) = split " ";

   # $id eq "FAM" indicates the start of a new family, with the second
   # field ($relation) holding the family ID.
   $curr_fam = $relation, next if $id eq "FAM";

   # Line must be an individual.  Push the ID on to the array for the
   # current family.
   push @{ $individuals{$curr_fam} }, $id;
}

I hope that makes sense.  The last line is the only one that's really
interesting.  I do exactly what I described above - use the *value* in
%individuals associated with the key $curr_fam and treat the value as
an array reference, hence the "@{" stuff that precedes it.

Here's the code to print out the hash:

foreach my $fam ( keys %individuals ) {
   foreach my $ind ( 0 .. $#{ $individuals{$fam} } ) {
      print "\$individuals{$fam}[$ind] = \"", $individuals{$fam}[$ind],
         "\"\n";
   }
}

You know, it might make more sense if you organized your structure
like this:

$individuals{"F1"}{"HUSB"} = "I10";
$individuals{"F1"}{"WIFE"} = "I8";
$individuals{"F1"}{"CHILD"} = ("I11", "I12");

That way you retain the information on the relationships between the
various family members.  Ooh, ooh, ooh, I get to say it:

"I'll leave that as an exercise to the reader."

I hope that helps,

---Jason


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to