Re: How to maintain hash relationship?
am 19.12.2007 15:46:17 von billOn Dec 17, 5:07 pm, Fred
> I'm not sure if I'm phrasing the question correctly, but here goes -- In
> ...
Fred,
I've modified your original code to do what it sounds like you want it
to do. You also mentioned returning a hash, so I included two ways of
doing that. Enter a city on the command line and look at the code
near
the end of the main() "section". You could also use a hash keyed on
the
city which pointed to an array of name records.
-Bill
#!/usr/local/bin/perl
use strict;
use warnings;
my %field_pos;
my %people;
%field_pos =
(
'FIRST_NAME', 0,
'LAST_NAME', 1,
'CITY', 2,
);
# Save where __DATA__ starts in our script
# so we can get back there for sub-sequent
# reads (this must occur prior to the first
# read from )
#
my $DATA_START_POS = tell(DATA);
# Altered original
#
while ( )
{
chomp;
s/\s$//;
my @data = split /\s*,\s*/;
my $key = "$data[1], $data[0]";
map { $people{$key}->{$_} = $data[$field_pos{$_}] } keys
%field_pos;
}
show_hash('people', \%people);
#-----------------------------
# Alternate version 1
#
my %people1 = get_data1();
show_hash('people1', \%people1);
#-----------------------------
# Alternate version 2
#
my %people2;
get_data2(\%people2);
show_hash('people2', \%people2);
# Show any people that live in the city entered on the command line
#
print "\n";
my $found = 0;
if ( $ARGV[0] )
{
foreach my $key ( sort keys %people )
{
my $rec = $people{$key};
next unless ( $ARGV[0] eq $rec->{CITY} );
print "$rec->{FIRST_NAME} $rec->{LAST_NAME} lives in
$ARGV[0]\n";
$found++;
}
}
printf "\n%s in $ARGV[0]\n", ( $found )
? sprintf "$found %s", ( $found == 1 ) ?
'person lives' : 'people live'
: "No one lives";
#END main()
sub get_data1
{
my %rethash;
# Rewind __DATA__ to its beginning
#
seek(DATA, $DATA_START_POS, 0);
while ( )
{
chomp;
s/\s$//;
my @data = split /\s*,\s*/;
my $key = "$data[0] $data[1]";
map { $rethash{$key}->{$_} = $data[$field_pos{$_}] } keys
%field_pos;
}
return(%rethash);
}
sub get_data2
{
my($hashref) = @_;
# Rewind __DATA__ to its beginning
#
seek(DATA, $DATA_START_POS, 0);
while ( )
{
chomp;
s/\s//g;
my @data = split /,/;
my $key = "$data[1]$data[0]";
map { $$hashref{$key}->{$_} = $data[$field_pos{$_}] } keys
%field_pos;
}
# Since $hashref is just the "address" of %people2, the
# assignments we made were directly to %people2 so there's
# nothing to return (although you could return something
# like the number of records read)
}
sub show_hash
{
my($title, $hashref) = @_;
print "\n'$title' hash:\n";
foreach my $key ( sort keys %$hashref )
{
my $rec = $$hashref{$key};
printf " %-20s: %-7s %-13s %s\n", $key, $rec->{FIRST_NAME},
$rec->{LAST_NAME}, $rec->{CITY};
}
}
__DATA__
Fred, Flintstone, Bedrock
Wilma, Flintstone, Bedrock
Barney, Rubble, Moonrock